自关闭 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#