2

My expectation is that is this the case, that after creating a NamedPipeServerStream with PipeOptions.Asynchronous (and the client side as well), that one can still perform synchronous Read/Write operations on the pipe.

However, I have found that when the server synchronously writes bytes which exceed the size of the out buffer, the client end blocks on the read, never to return, even though the server has written the appropriate amount of data to satisfy that read.

Update: I have not yet been able to make a simple repro case, but I have isolated what I think to be suspicious results from the PipeStream class. I have the following code:

byte[] buffer = new byte[ 66754 ];
int n1 = pipeStream.Read( buffer, 0, 66754 ); // Read returns 65536
int n2 = pipeStream.Read( buffer, buffer.Length - 1218, 1218 ); // Read blocks

This code is executed under the circumstances where the other side of the pipe has written 66754 bytes of data and the read side has not yet read this data (note, that the in and out max buffersize of the pipe at both ends is 65536 and that 65536 + 1218 == 66754).

When this code executes, the first read returns with n1 == 65536, indicating that not all the data I expected was read, so I execute another read, asking for the remaining data. This read blocks indefinitely, never to return.

However, before the second read, when I inspect the buffer, I see the expected data that was written, even after the 65535 position!

It seems like the first Read read all the data, but only returned the max buffer size, so the second read hangs because there is no more data to be read. But, I do not know that because I was told, incorrectly, the amount of data read on the first Read.

Now, a slight modification to this code. This new code runs in exactly the same conditions as the previous.

byte[] buffer = new byte[ 66754 ];
int n1 = pipeStream.Read( buffer, 0, 65536); // Read returns 65536
int n2 = pipeStream.Read( buffer, buffer.Length - 1218, 1218 ); // Read blocks

Note that now the first Read has asked to read only the max buffer size of 65536. In this case, n1 == 65536, and when the second read takes place, it returns successfully with n2 == 1218.

Here, instead of the first read asking for all the data, it asks for the max buffersize. These are expected correct results of the Reads.

This suggests that there is a bug in the PipeStream code, where it returns the incorrect value from Read.

I will continue to try to make a simple repro case for this.

Another Update: Found this: NamedPipe's ReadByte hangs Seems relevant to my issues.

Eric Vasilik
  • 362
  • 2
  • 14
  • Have you seend this example code https://stackoverflow.com/questions/13806153/example-of-named-pipes/13806752#13806752 ? – I4V Aug 31 '17 at 21:21
  • Hi I4V, I have seen this code. It opens a pipe in synchronous mode, and read/writes on sync mode. However, I need to open the pipe in async mode so that I can shut the pipe down. See https://stackoverflow.com/questions/607872/what-is-a-good-way-to-shutdown-threads-blocked-on-namedpipeserverwaitforconnect for a description as to why it must be connected to async. – Eric Vasilik Aug 31 '17 at 21:24
  • I don't understand `I need to open the pipe in async mode so that I can shut the pipe down` If stream returns null, that means channel is closed. – I4V Aug 31 '17 at 21:28
  • Sorry, I edited the previous response with the relevant info for that. Please see https://stackoverflow.com/questions/607872/what-is-a-good-way-to-shutdown-threads-blocked-on-namedpipeserverwaitforconnect. It describes why the pipe must be async. – Eric Vasilik Aug 31 '17 at 21:29
  • And I propose a simpler method. check if it returns null (that is valid for every stream in .NET. FileStream, NetworkStream etc. No need for *IsConnected* or similar methods) – I4V Aug 31 '17 at 21:30
  • I do not understand, what function is to return null? My problem is that a read operation blocks indefinitely when it should not, and I am wondering if it is legal to perform sync operations on an async pipe. – Eric Vasilik Aug 31 '17 at 21:33
  • *NamedPipeClientStream* or *NamedPipeServerStream* is a *Stream*. if any read operation on it returns null, it means connection is lost. `My problem is that a read operation blocks indefinitely when it should not` This means you have a bug somewhere. Maybe you may want to use *Flush* while sending. Waiting till a new data is available is a normal behaviour – I4V Aug 31 '17 at 21:37
  • The Read operations are not returning null (or zero, in this case, as they return int). The read call is blocking, and not returning at all. – Eric Vasilik Aug 31 '17 at 21:38
  • I updated my previous comment – I4V Aug 31 '17 at 21:38
  • I do Flush the write stream, and I've debugged it to the point that I have confirmed that enough data is written to the pipe to satisfy the read, yet the read blocks. I am at the point where I am questioning my usage of an async pipe to have sync read and write operations applied to them. That is my primary question: Can I call Read and Write methods on an async pipe? – Eric Vasilik Aug 31 '17 at 21:41
  • @EricVasilik I think a [Minimal, Complete, and Verifiable Example](https://stackoverflow.com/help/mcve) that demonstrates the issue would be helpful in clearing up any confusions like I4V is having. – Scott Chamberlain Sep 01 '17 at 03:47
  • I've been trying to get a simple repro case, but have not been successful. I will, however, update the question with some more information of what I am seeing. – Eric Vasilik Sep 04 '17 at 19:26

0 Answers0