2016-04-08 64 views
0

我有一个单身般的类,它可以做一些日志输出:当我使用冲洗的StreamWriter

,在一个示例程序像

class Program 
{ 
    private static void Main(string[] args) 
    { 
     Foo.Instance.Log("asdf\n"); 
    } 
} 

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

我试图打电话给Close()~Foo()修复类:

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

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

如何确保我的StreamWriter“最后”被刷新?

编辑

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

+0

实现[IDisposable接口](https://msdn.microsoft.com/en-us/library/system.idisposable(v = vs.110).aspx) – Steve

+0

我想到了这一点,但在给出的例子中'Dispose()'不会被调用。 – mkluwe

+0

这是一个析构函数。它是不同的见:http://stackoverflow.com/questions/339063/what-is-the-difference-between-using-idisposable-vs-a-destructor-in-c – Steve

回答

0

首先,使用单例会产生问题本身,这并不需要另一个证明。在这里,这是一个伪装的全球清理。该StreamWriter不会自动刷新的程序结束,并根据the documentation

必须调用关闭,以确保所有数据被正确地写入到底层流。

感谢回答“Self-closing StreamWriter singleton”从@PeterDuniho一个可能的解决方案可以改变构造函数

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

考虑在析构函数调用Close()的问题,我不应该忽视“无论如何,“终结者并没有多大用处”。在这种情况下,由于垃圾收集不使用特定顺序,因此StreamWriter对象已被收集并且无法在复活的僵尸状态下关闭。

0

您可以使用具有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); 
    } 
}