2011-10-18 65 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