0

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?

Community
  • 1
  • 1
kgh
  • 157
  • 1
  • 12
  • Where does _stream come from? What is the actual error / symptom? This question is unclear and incomplete. – H H Dec 01 '14 at 17:31

3 Answers3

6

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.

Servy
  • 202,030
  • 26
  • 332
  • 449
  • Note that `StreamWriter` will try to dispose stream too if you `using (StreamWriter s...)` ... One need to be careful mixing writers and raw streams - at very least `.Flush()` writer when you are done. – Alexei Levenkov Dec 01 '14 at 17:26
4

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.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
2

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();
      }
    }
}
Ahmad
  • 8,811
  • 11
  • 76
  • 141