2011-10-18 43 views
1

时,这是一个记录类构造函数抛出异常:C#FileLogTraceListener关闭

public QFXLogger(
     int maxFileSize, 
     TraceLevel logLevel) 
    { 
     this.maxFileSize = maxFileSize; 
     logSwitch.Level = logLevel; 
     //Configure log listener 
     traceListener = new FileLogTraceListener(); 
     traceListener.DiskSpaceExhaustedBehavior = DiskSpaceExhaustedOption.DiscardMessages; 
     traceListener.CustomLocation = @".\Log"; 
     traceListener.BaseFileName = "QFXLog"; 
     traceListener.AutoFlush = true; 
     //Remove all other listeners 
     Trace.Listeners.Clear(); 
     //Add QFX listener 
     Trace.Listeners.Add(traceListener); 
     //Write header 
     WriteSessionHeader(); 
    } 

这是destrcutor:

~QFXLogger() 
    { 
     WriteSessionFooter(); 
     traceListener.Close(); 
    } 

我只想之前写一个页脚底层流记录器获取GC。 没有析构函数一切都很好,但它我得到以下几点:

Unhandled Exception: System.ObjectDisposedException: Cannot access a closed file 
. 
at System.IO.__Error.FileNotOpen() 
at System.IO.FileStream.Flush(Boolean flushToDisk) 
at System.IO.FileStream.Flush() 
at System.IO.StreamWriter.Flush(Boolean flushStream, Boolean flushEncoder) 
at System.IO.StreamWriter.Flush() 
at Microsoft.VisualBasic.Logging.FileLogTraceListener.ReferencedStream.CloseS 
tream() 
at Microsoft.VisualBasic.Logging.FileLogTraceListener.CloseCurrentStream() 
at Microsoft.VisualBasic.Logging.FileLogTraceListener.Write(String message) 
at System.Diagnostics.TraceInternal.Write(String message) 
at System.Diagnostics.Trace.Write(String message) 
at QFXShell.QFXLogger.WriteSessionFooter() 
at QFXShell.QFXLogger.Finalize() 

在我看来,底层流已经关闭。

我该如何抑制这种关闭(底层流)或者这是另一个问题?

+0

@Ramhound WriteSessionFooter除此之外不做任何事情:Trace.Write(footerString);问题是我想在应用程序关闭之前编写结束语句。 – Juergen

+0

当我在我的类的IDisposable接口实现中调用Stream.Dispose()时发生了此ObjectDisposedException,但在移除对Stream.Flush()的调用函数调用后停止了此操作。 – Roger

+0

哎呀,说得太快。通过确保我的Dispose(bool isFreeingManagedResources)函数被虚拟保护,解决了这个问题,正如Kelly Leahy在他的网站上解释的那样。以前,我把它当作私人的。 – Roger

回答

2

c#中的终结器(析构函数)不应该用在这个方法中。终结器仅用于以释放非托管资源。当调用终结器时,access to other .net objects is not guaranteed只应释放您直接分配的非托管资源。

敲定操作具有以下限制:

  • 两个对象的终结不能保证在任何特定的顺序运行,即使一个对象引用另一个。也就是说,如果对象A具有对象B的引用并且都具有终结器,则在对象A的终结器开始时对象B可能已经完成。

你需要做的是落实IDisposable Interface正确关闭你的日志文件。一些附加信息可以在Kelly Leahy's IDisposable and Garbage Collection找到。

如果你没有处于一次性类的帮助(全局对象等)的情况下,你总是可以自己实现一个Close方法来确保文件在发布前是有效的。

+0

@谢谢,我会仔细看看。 – Juergen

1

关闭析构函数中的tracer对象为时已晚。在这一刻,很多不再需要的物体都可以被处理掉。

我会建议使用公共Dispose方法实现一个IDisposable接口,并在您知道不再需要此QFXLogger对象时立即调用此方法。在这个Dispose方法中,我会检查tracer对象是否不是NULL,然后打开它,然后调用Close。

有关更多详细信息,请参阅Proper use of the IDisposable interface