自关闭 StreamWriter 单例
Self-closing StreamWriter singleton
我试图在 实现类似单例的自关闭 StreamWriter
:
中进一步缩小问题范围
class Foo : System.IO.StreamWriter
{
private static readonly Foo instance = new Foo( "D:/tmp/test" );
private Foo( string path )
: base( path )
{
}
~Foo()
{
this.Close();
}
public static Foo Instance
{
get
{
return instance;
}
}
}
预期的效果是在像
这样的示例程序中
class Program
{
private static void Main( string[] args )
{
Foo.Instance.Write( "asdf\n" );
}
}
垃圾收集器导致 Foo
的实例关闭。
这行不通。显然,当 Foo
的析构函数运行时 StreamWriter
已经消失,我得到一个 System.ObjectDisposedException
.
如何以适当的方式在流上调用 Close()
并防止数据丢失?
Apparently, the StreamWriter is already gone when Foo's destructor runs
是的。在程序终止时,假设您的对象完全被 GC 处理(不能保证一定会这样),运行time 不提供任何关于它执行终结器的顺序的保证。两个对象都无法访问并且同时符合终结条件,因此它们的终结器可以 运行 以任何顺序排列。
终结器仅作为错误代码的后盾。而且它们也不是 100% 可靠的。这就是为什么你应该努力避免错误代码。
您需要一种确定性的方法来在进程退出时处理单例对象。您可以将其置于控制进程生命周期的程序主要逻辑的控制中,并让它处理单例(例如,通过您为此目的编写的 public 方法)。另一种选择是在单例的构造函数中订阅 AppDomain.ProcessExit
事件,并让处理程序在那里关闭单例。
查看这些相关问题以获取更多信息:
How can I ensure that I dispose of an object in my singleton before the application closes?
Disposable singleton in C#
我试图在 StreamWriter
:
class Foo : System.IO.StreamWriter
{
private static readonly Foo instance = new Foo( "D:/tmp/test" );
private Foo( string path )
: base( path )
{
}
~Foo()
{
this.Close();
}
public static Foo Instance
{
get
{
return instance;
}
}
}
预期的效果是在像
这样的示例程序中class Program
{
private static void Main( string[] args )
{
Foo.Instance.Write( "asdf\n" );
}
}
垃圾收集器导致 Foo
的实例关闭。
这行不通。显然,当 Foo
的析构函数运行时 StreamWriter
已经消失,我得到一个 System.ObjectDisposedException
.
如何以适当的方式在流上调用 Close()
并防止数据丢失?
Apparently, the StreamWriter is already gone when Foo's destructor runs
是的。在程序终止时,假设您的对象完全被 GC 处理(不能保证一定会这样),运行time 不提供任何关于它执行终结器的顺序的保证。两个对象都无法访问并且同时符合终结条件,因此它们的终结器可以 运行 以任何顺序排列。
终结器仅作为错误代码的后盾。而且它们也不是 100% 可靠的。这就是为什么你应该努力避免错误代码。
您需要一种确定性的方法来在进程退出时处理单例对象。您可以将其置于控制进程生命周期的程序主要逻辑的控制中,并让它处理单例(例如,通过您为此目的编写的 public 方法)。另一种选择是在单例的构造函数中订阅 AppDomain.ProcessExit
事件,并让处理程序在那里关闭单例。
查看这些相关问题以获取更多信息:
How can I ensure that I dispose of an object in my singleton before the application closes?
Disposable singleton in C#