Non-blocking way to check for StreamReader data

I have a StreamReader , and I want to know if data is available without blocking the stream.

I tried the Peek method, but it gets blocked when there is no data available.

 using (StreamReader reader = new StreamReader(stream)) { if (reader.Peek() == -1) // Blocks here while there is no data and unblocks as soon as there is data. { } } 

If I check the peek () method mono code , it says in the comment

  // // Peek can block: // http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=96484 // 

Unfortunately, the link no longer works.

I found here , here , here, and here that Microsoft seems to have an error causing Peek block. But all these posts are pretty old. I think mono initially made Peek() lock due to this error.

So I have two questions

  • Is it true that Microsoft has an error causing Peek() lock? If not, mono should change its Peek() implementation as non-blocking.
  • Is there another way to check if StreamReader has data available without blocking the stream?
+8
c # mono
source share
2 answers

Ok, let me just say that I really don’t know what you are trying to do here. However, from what I see, the Peek method must block the current thread in order to work. This is what the documentation says:

The Peek method returns an integer value to determine whether the end of the file or another error. This allows the user to first check if the return value is -1 before passing it to the Char Type.

So Peek should only return -1 if it detects an error or the end of the file. This is a bit confusing because there can be no file. The stream may be a response from WebRequest , in which case the part of the stream you are trying to read is not yet loaded. Thus, Peek must wait until it is executed, because, and this is not clear from the documentation, it returns the first byte read from the stream.

The problems mentioned in the links you posted are related to multiple streams using the same StreamReader , which is not your business. I also believe that there used to be an error due to which one StreamReader waiting for input to block another, but I believe that it has since been fixed. I'm not sure what the Mono implementation does.

To answer your question, to do this without blocking the thread, I would try the following:

  • Just put it all in a separate thread. Then you don't care if it’s blocked or not.
  • Use ReadAsync and then await or ContinueWith in the task to make it non-blocking.

However, as was correctly noted in the comments, if you put all this in a different thread, do you really need Peek ? Why not just put it in your typical while (Read(...)) { ... } block and process the data as it gets closer?

0
source share
  • I cannot give answers, I have no specific case for reproduction and testing, and, obviously, the source is not available.
  • With .NET 4.5, you can use the ReadAsync method from the StreamReader class
0
source share

All Articles