Search code examples
c#multithreadingasynchronoususingsystem.io.pipelines

My program crashes when I add the using keyword before a StreamReader, why?


I have a method which starts a DispatcherTimer that reads all messages from a System.IO.Pipes.NamedPipe. Before the timer starts, I want to read the first message.

// Initiate the PipeClient
pipeClient = new NamedPipeClientStream(".", pipeName, PipeDirection.In);
pipeClient.Connect();

//declare executionSymbol
var reader = new StreamReader(pipeClient);
string executionSymbol = reader.ReadLine();

//start reading the messages
timer = new DispatcherTimer();
timer.Interval = TimeSpan.FromMilliseconds(100);
timer.Tick += async (sender, e) => {
    // Empty the Pipe...
};
timer.Start();

This works fine so far, but just because i was curious i made this change.

//declare executionSymbol
using (var reader = new StreamReader(pipeClient)) {
    string executionSymbol = reader.ReadLine();
}

I was not expecting it to have any practical change, but as it turns out, it crashes my Program as soon as the method is called. Why does this happen? Feel free to ask me for more information!


Solution

  • At the end of the using block, your StreamReader is disposed. Disposing a StreamReader has the side-effect of closing the underlying stream.

    The next time you access pipeClient (your underlying stream), you access a disposed stream, and, thus, get an exception. You haven't shown us your complete code, but I have a hunch that this is what happens in timer.Tick.

    To fix this, you have the following options:


    Oh, and some general hints to make your software development life easier:

    • Add a global, top-level exception handler to your application. That way, it will not crash but report exception details (in some way that is useful for you) and close gracefully.

    • The next time you ask a question on StackOverflow, add the exact text of the exception directly to your question. That way, people won't have to guess what crashes your program, but can check the exception message and the stack trace.