For*_*bie 6 .net c# singleton garbage
我有一个单一的记录器类.在它的析构函数中,我调用Close()打印日志的页脚,然后关闭StreamWriter.
public void Close()
{
WriteLogFileFooter();
_logFile.Flush();
_logFile.Close();
}
Run Code Online (Sandbox Code Playgroud)
问题是当从程序中的其他地方调用System.Enviornment.Exit(1)时(我自己没有编写的部分),页脚永远不会打印,我的记录器会因尝试写入封闭流而抛出异常.我只能假设Exit命令导致我的StreamWriter在我的Singleton被破坏之前被关闭.我尝试在我的StreamWriter上使用GC.SupressFinalize(),但这似乎没有帮助.
Eri*_* J. 12
您违反了终结器的一条明确规则:
Finalize方法不应引用任何其他对象.
http://msdn.microsoft.com/en-us/library/b1yfkh5e(v=VS.90).aspx
在应用程序退出时收集对象之前,收集引用的托管对象完全有可能被收集.
UPDATE
如果您需要在应用程序退出时清理托管资源,则可以挂接AppDomain 的ProcessExit事件,而不是依赖于终结器执行的非确定性行为.
您应该让您的记录器实现IDisposable,并在using块中使用它。这意味着它将被确定性地处置,而现在它正在被非确定性地破坏。
错误的原因是您的流有时会在记录器之前关闭,因为Exit基本上会破坏所有内容(不确定)并退出。您应该使用确定性模式 ( IDisposable) 来避免这种情况。
实际上,析构函数在 C# 中很少有用,因为它们是不确定的。它们只值得用于释放非托管资源。
另外,实现IDisposable可能会使使用单例变得不方便。我个人认为最好创建一个在整个程序中使用并在最后处理的实例,而不是显式的单例。