在其生命周期结束时刷新 StreamWriter

Flush StreamWriter at the end of its lifetime

我有一个类似单例的 class 可以做一些日志输出:

class Foo
{
    private static Foo instance;
    private System.IO.StreamWriter os;

    private Foo()
    {
        this.os = System.IO.File.CreateText( "D:/tmp/test" );
    }

    public static Foo Instance
    {
        get
        {
            if ( instance == null )
                instance = new Foo();
            return instance;
        }
    }

    public void Log( string s )
    {
        os.Write( s );
    }
}

当我在像

这样的示例程序中使用它时
class Program
{
    private static void Main( string[] args )
    {
        Foo.Instance.Log( "asdf\n" );
    }
}

正在创建文件,但未写入任何输出。我认为这是因为 StreamWriter 从未被刷新过。

我试图通过调用 ~Foo() 中的 Close() 来修复 class:

~Foo()
{
    os.Close();
}

但这会产生 ObjectDisposedException。显然,当 Foo 的析构函数被调用时,Foo.os 已经被释放了。

如何确保我的 StreamWriter 被刷新 "at last"?

编辑

设置 this.os.AutoFlush = true; 有效。将 Flush() 方法添加到 Foo 并在适当的地方调用它也是如此,但我很感兴趣是否有任何方法可以不用。

您可以使用具有 Flush 方法的 StreamWriter。

对于您要完成的任务,还有另一种选择,您可以使用 File.AppendAllText 并且会起作用。这样就不会一直打开StreamWriter

class Foo
{
    private static Foo instance;
    private System.IO.StreamWriter os;

    private Foo()
    {
        this.os = new System.IO.StreamWriter("D:/tmp/test.txt");
    }

    public static Foo Instance
    {
        get
        {
            if (instance == null)
                instance = new Foo();
            return instance;
        }
    }

    public void Log(string s)
    {
        os.WriteLine(s);
        os.Flush();
    }

    public void Log2(string s)
    {
        System.IO.File.AppendAllText(@"D:/tmp/test2.txt",s);
   }
}

首先,使用单例本身就会产生问题,这不需要其他证明。在这里,它是对伪装的全局的清理。 StreamWriter 不会在程序结束时根据 the documentation

自动刷新

You must call Close to ensure that all data is correctly written out to the underlying stream.

感谢@PeterDuniho 对“”的回答,可能的解决方案是将构造函数更改为

private Foo()
{
    this.os = System.IO.File.CreateText( "D:/tmp/test" );
    System.AppDomain.CurrentDomain.ProcessExit +=
        (sender, eventArgs) => this.os.Close();
}

考虑到在析构函数中调用Close()的问题,我不应该忽略到处写的"finalizers are not of much use anyway"。在这种情况下,由于垃圾回收没有使用特定的顺序,StreamWriter 对象已经被回收并且无法在其复活的僵尸状态下关闭。