Strange behavior of the Trace

I use Trace class to get logs of the Windows Service. Log file could be changed dinamicalli (you change log file name and trace should to create new file and continue write trace in them).

STrace (my class) contain such function to dinamically change log file:

private static void AddTextListener(string FileName)

{

//===========================================================

Trace.WriteLine(DateTime.Now.ToString("yyyy/M/d hh:mm:ss", DateTimeFormatInfo.InvariantInfo) +

" Names before");

for (int i = 0; i < Trace.Listeners.Count; i++)

{

Trace.WriteLine(Trace.ListenersIdea.Name);

Trace.Flush();

}

Trace.WriteLine("================================");

Trace.Flush();

//===========================================================

// Remove and close the file writer/trace listener.

if (myTextListener != null)

{

Trace.WriteLine(DateTime.Now.ToString("yyyy/M/d hh:mm:ss", DateTimeFormatInfo.InvariantInfo) +

" Before deleting text listener. FileName: " + myTextListener.Name);

myTextListener.Flush();

Trace.Listeners.Remove(myTextListener);

myTextListener.Close();

}

// Create a file for output.

String myFileName = FileName;

StreamWriter myOutputWriter = new StreamWriter(myFileName, true);

// Add a TextWriterTraceListener for the file.

myTextListener = new TextWriterTraceListener(myOutputWriter);

myTextListener.Name = myFileName;

Trace.Listeners.Add(myTextListener);

Trace.WriteLine(DateTime.Now.ToString("yyyy/M/d hh:mm:ss", DateTimeFormatInfo.InvariantInfo) +

" After adding text listener. File name: " + myTextListener.Name);

//===========================================================

Trace.WriteLine(DateTime.Now.ToString("yyyy/M/d hh:mm:ss", DateTimeFormatInfo.InvariantInfo) +

" Names after");

for (int i = 0; i < Trace.Listeners.Count; i++)

{

Trace.WriteLine(Trace.ListenersIdea.Name);

Trace.Flush();

}

Trace.WriteLine("================================");

Trace.Flush();

//===========================================================

}

Windows service starts and stop automatically.

Result log - show only 2 Trace.Listeners - Default and TextWriterListener.

But if I use the code which add or remove Listeners in different functions:

Function(string newLog)

{

if (logFile == NewLog)
                return false;
Trace.Listeners.Remove(logFile);
logFile = NewLog;
Trace.Listeners.Add(new TextWriterTraceListener(logFile));

}

Service starts, I change log file name - service CREATES new log file but you CAN NOT to delete old log file. It seems that log file isn't released.

 

In principle I need answer on siimple question:

Could I by some methode to make forced file releasing




Answer this question

Strange behavior of the Trace

  • Matthias Eck

    You're not closing the file you opened with the new StreamWriter() statement. The Trace object stops writing to it but the file is still locked. You need to restructure your code so that you call myOutputWriter.Close() when you remove the listener.



  • R. P. Poletti

    Yes, it is a local variable. No, it doesn't close the file after the function finishes. That's why you need to restructure your code, you need to keep the myOutputWriter around so you can close the file.



  • lsamp

    In principal - very strange...

    I though that is needing two functions:

    Trace.Listeners.Add(TraceListener tl);

    Trace.Listeners.Remove(string FileName);

    And it is enough to perform File handle acquire/release, but in real it is undefined :(.



  • Michael Giagnocavo

    But myOutputWriter is LOCAL variable and free file automatically after function finish - isn't so

  • R.Trifonov

    Umm, no, probably not. It is important that you understand why it works that way. Just because you create the StreamWriter object and assign its reference to a local variable doesn't mean it gets garbage-collected when the local variable goes out of scope. For one, the Trace object still has a reference to it which will keep it alive. That is a good thing, you wouldn't want to suddenly see the StreamWriter object disappear, the Trace class code will crash when it tries to write the data to the file.

    I don't really know what happens to a StreamWriter object when all references to it disappear (Trace.Listeners.Remove); I just never tried to do that. Your problem suggests that the object keeps living because it still has an opened file handle. Makes sense to me. Of course, your program will leak file handles and keeps files locked...



  • JessieLiu

    OK

    I, definitly, try to do that. One more question - with FileInfo - such situation



  • Strange behavior of the Trace