使用多个流到多个文件会产生System.ObjectDisposedException“无法访问已关闭的文件”。

时间:2015-04-13 20:29:48

标签: c# stream

我想让多个记录器写入不同的文件。写入部分有效但当我关闭Logger对象时,我得到System.ObjectDisposedException"无法访问已关闭的文件。"

class Program
{
    static void Main(string[] args)
    {
        Logger logger1 = new Logger("file1.txt");
        Logger logger2 = new Logger("file2.txt");
        logger1.WriteLog("abcd");
        logger2.WriteLog("abcd");
        Console.WriteLine("Done");
    }
}

class Logger
{
    private StreamWriter writer;

    public Logger(string filePath)
    {
        writer = File.AppendText(filePath);
    }

    ~Logger()
    {
        try
        {
            writer.Close();
        }
        catch (Exception)
        {

            throw;
        }
    }

    internal void WriteLog(string p)
    {
        writer.WriteLine(p);
    }
}

2 个答案:

答案 0 :(得分:3)

与问题中所说的相反,您没有关闭任何记录器。我假设在Logger完成时,终结器线程上会发生此异常。这是因为无法保证完成订单。 StreamWriter可能先死了。

删除终结器。它没有用处,因为StreamWriter在完成时(或它写入的流;不确定)关闭自己。并且您无论如何都无法确定性地清除所有数据(请参阅下面的评论)。这种策略注定要失败。你需要扔掉它。

实施一次性模式并切换到确定性清理。

答案 1 :(得分:0)

如果您需要做的只是打开一个文件,写一条短信然后关闭它,就像你发布的那个小应用程序一样,你可以考虑使用File.AppendAllText

File.AppendAllText("file1.txt", "abcd");

您甚至可以按原样保留“主要”代码,并编写一个简短的帮助函数来使用。这消除了处理任何东西的需要,因为File.AppendAllText会为你处理它。

class Logger
{
    private readonly string logFileName;

    public Logger(string logFileName)
    {
        this.logFileName = logFileName;
    }

    internal void WriteLog(string message)
    {
        File.AppendAllText(logFileName, message);
    }
}

当然,StreamWriter的一个优点是,每次编写邮件时都不会访问磁盘,除非您将AutoFlush设置为true。 YMMV。