kgh
kgh

Reputation: 167

Write to file with FileStream without using "using"

I have a class member variable _stream which is a FileStream. This variable gets initialized in the constructor and needs to stick around until I'm done with the class. I have another class that raises an event every time something needs to be written to the file. In my main class I have an event handler that performs the actual writing. I tried the following code as in this question:

void MyEventHandler(string message)
{
    using (_stream)
        using (StreamWriter s = new StreamWriter(_stream))
           s.WriteLine(message);
}

But this doesn't work because using disposes of my FileStream before I'm done with it. What should I be doing instead?

Upvotes: 0

Views: 2649

Answers (3)

Ahmad
Ahmad

Reputation: 9658

using is used for local variables in a function to implicitly dispose the object, but when it is a member of a class you should dispose it when the class is disposed.

class YourClass : IDisposable
{
    ....
    public void Dispose()
    {
       Dispose(true);
    }

    protected virtual void Dispose(bool disposing)
    {
      if (disposing)
      {
        _stream.Dispose();
      }
    }
}

Upvotes: 2

Jon Skeet
Jon Skeet

Reputation: 1499760

Firstly, you clearly need to remove the using (_stream) as that will dispose of the stream directly.

Secondly, the StreamWriter will also dispose of the stream as well, with your current code. Options for this are:

  • Don't have a using statement for the StreamWriter either, but explicitly flush the writer if you need it to be written to the file immediately:

    void MyEventHandler(string message)
    {
        var s = new StreamWriter(_stream);
        s.WriteLine(message);
        s.Flush();
    }
    
  • Use the constructor for StreamWriter which allows you to control whether or not the stream is closed when the StreamWriter is disposed:

    void MyEventHandler(string message)
    {
        using (var s = new StreamWriter(_stream, Encoding.UTF8, 1024, true))
        {
             s.WriteLine(message);
        }
    }
    
  • Change your code so that instead of a Stream, the field in your class is a TextWriter to start with (which is initialized as a StreamWriter for whatever file/stream you want) - then you don't need to create a new StreamWriter in the method at all.

As Servy notes, your own class should implement IDisposable and dispose of the stream/writer in its Dispose method.

Upvotes: 4

Servy
Servy

Reputation: 203802

Just omit the using.

Note that in this case the class that is defining this method should implement IDisposable and it should dispose of the stream in its Dispose method. The user of this class should declare it in a using block.

Upvotes: 6

Related Questions