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();
}
这是析构函数:
~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()
在我看来,底层流已经关闭。
我如何抑制(底层流的)关闭或者这是另一个问题?
This is a logging class with a constructor:
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();
}
And this is the destrcutor:
~QFXLogger()
{
WriteSessionFooter();
traceListener.Close();
}
I just want to write a footer to the underlying stream before the logger gets GC.
Without the destructor everything is fine, but with it I get the following:
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()
It seems to me that the underlying stream was already closed.
How can I suppress this closing(of the underlying stream) or is this another issue?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
此方法中不应使用 C# 中的终结器(析构函数)。终结器仅用于释放非托管资源。调用终结器时,不保证访问其他 .net 对象 并且应该只释放您直接分配的非托管资源。
您需要做的是实现 IDisposable Interface 以正确关闭你的日志文件。一些其他信息可以在 Kelly Leahy 的 IDisposable 和垃圾收集中找到。
如果您没有遇到一次性类可以提供帮助的情况(全局对象等),您始终可以自己实现一个 Close 方法,以确保文件在发布之前有效。
Finalizers (destructors) in c# should not be used in this method. Finalizers are intended only to release unmanaged resources. When a finalizer is called, access to other .net objects is not guaranteed and should only release unmanaged resources that you directly allocated.
What you need to do is implement the IDisposable Interface to properly close your logging file. Some additional information can be found at Kelly Leahy's IDisposable and Garbage Collection.
If you are not in a situation where a disposable class will help (global object, etc.) you can always implement a
Close
method yourself to ensure the file is valid before it is released.在析构函数中关闭跟踪器对象为时已晚。此时,许多不再需要的对象已经可以被处理掉。
我建议使用公共 Dispose 方法实现 IDisposable 接口,并在您知道不再需要此 QFXLogger 对象时立即调用此方法。在此 Dispose 方法中,我将检查跟踪器对象是否不为 NULL、打开,然后对其调用 Close。
有关更多详细信息,请参阅正确使用 IDisposable 接口。
It is too late for you to close the tracer object in the destructor. In this moment a lot of objects which are not needed any more can be already disposed.
I would propose to implement a IDisposable interface with a public Dispose method and to call this method as soon as you know that you are not going to need this QFXLogger object any more. In this Dispose method, I would check if the tracer object is not NULL, open and then I would call Close on it.
See Proper use of the IDisposable interface for more details.