1

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!

Theodor Zoulias
  • 34,835
  • 7
  • 69
  • 104
0q_
  • 74
  • 4
  • 1
    Do you have the exception info? – BitWiseByteDumb Mar 26 '23 at 20:45
  • And what documentation of StreamReader constructor says?(the one which takes Stream as parameter) – Selvin Mar 26 '23 at 20:49
  • 1
    _I was not expecting it to have any practical change_ and why so? It has an important effect and it is the whole reason for its existance. It closes and disposes the object captured in the first line of the using block when you exit from that block. So you cannot use it again in the following code (probably inside the Tick event handler) – Steve Mar 26 '23 at 20:52
  • Hehe and how he could use reader outside using scope? – Selvin Mar 26 '23 at 20:53
  • Hello @Steve, I was only aware that the using keyword would dispose the object it was given. What i didnt know was that it would dispose the underlying objects that it was given. Sorry for asking a question on a forum about asking questions... – 0q_ Mar 26 '23 at 21:13

1 Answers1

2

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.

Heinzi
  • 167,459
  • 57
  • 363
  • 519
  • 1
    Hello! First of all thank you for your answer and the tips. Sadly i didn't have the exception, because I was starting this program externally and not from my IDE enviroment. But i guess if I had implemented such an exception handler as you pointed out it would have been easier. I wil try to ask my future questions better than this. Thanks! – 0q_ Mar 26 '23 at 21:09