简体   繁体   中英

When is StreamWriter disposed?

I have a small class I threw together to implement a quick logger. I composed it with a private System.IO.StreamWriter which is instantiated in the constructor. Because the way I'm using is prevents me from implementing a using block, I added a finalizer and called the StreamWriter's Dispose() method in it. However, when executing, that finalizer throws an exception because the StreamWriter has already been disposed.

System.ObjectDisposedException - Cannot access a closed file.

I'm confused how this happened and I'm wondering if this means I don't need to worry about cleaning up the StreamWriter. Here is my class:

public class TextFileLogger : AbstractTextLogger
{
    private const string LogPath = @"C:\";
    private const string LogFileName = "MyFile.log.txt";
    private readonly StreamWriter _writer;

    public TextFileLogger()
    {
        _writer = new StreamWriter($"{LogPath}{LogFileName}", true);
        _writer.AutoFlush = true;
    }

    ~TextFileLogger()
    {
        _writer.Dispose();
    }

    protected override void WriteLine(string line)
    {
        _writer.WriteLine(line);
    }
}

The only things you are allowed to access in a finalizer are objects that are rooted (like static variables) or objects that derive from CriticalFinalizerObject.

The problem is the finalizer is not deterministic, it is allowed to run in any order it feels like. The problem you ran in to is because the text writer was finalized before your class.

You need to either just "hope for the best" and let the writer's finalizer to do the work or you need to refactor your code so your class is disposeable itself and that calls the stream writer's dispose method.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM