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

时间:2016-04-08 13:33:24

标签: c# singleton streamwriter

我有一个类似单身的类可以做一些日志记录输出:

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从未被冲洗过。

我尝试通过致电Close()中的~Foo()来修复课程:

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

但这会产生ObjectDisposedException。显然Foo.os在调用Foo的析构函数时已被处理掉。

如何确保我的StreamWriter最后被“冲洗”?

修改

设置this.os.AutoFlush = true;有效。将Flush()方法添加到Foo并在适当的位置调用它也可以,但我感兴趣的是有没有办法。

2 个答案:

答案 0 :(得分: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);
   }
}

答案 1 :(得分:0)

首先,使用单身人士本身会产生问题,而这不需要另外证明。在这里,它是一个伪装的全球清理。根据{{​​3}},

If FolderBrowserDialog1.ShowDialog = DialogResult.OK Then For Each Documento As String In My.Computer.FileSystem.GetFiles(FolderBrowserDialog1.SelectedPath, FileIO.SearchOption.SearchTopLevelOnly) *Dim imagen As Image = Image.FromFile(Documento) DataGridView1.Rows(a).Cells(0).value = imagen a = a + 1 Next End If 不会在程序结束时自动刷新
  

您必须调用Close以确保所有数据都正确写入基础流。

感谢回答" the documentation"从@PeterDuniho可能的解决方案是将构造函数更改为

StreamWriter

考虑到在析构函数中调用private Foo() { this.os = System.IO.File.CreateText( "D:/tmp/test" ); System.AppDomain.CurrentDomain.ProcessExit += (sender, eventArgs) => this.os.Close(); } 的问题,我不应该忽略"终结器无论如何都没有多大用处。"写满了整个地方。在这种情况下,由于垃圾收集不使用特定的顺序,Close()对象已经被收集,并且无法在其复活的僵尸状态中关闭。