C#为什么我的命名管道read()方法没有阻塞?

时间:2018-04-19 00:18:19

标签: c# asynchronous ipc named-pipes blocking

我有一个方法,我打算使用namedPipeServerStream.Read()多次读取消息。管道是在Asynchronous属性设置为true的情况下启动的,因为我不希望等待连接阻塞。但是,阅读Microsoft文档并尝试其他示例,似乎Read()方法应该在调用时阻塞,直到管道中的数据被读取为止。
我使用的模式是创建管道,当建立连接时,调用一个使用Read()方法的方法。 Read()处于while循环中,直到IsMessageComplete属性返回true。此时输入是进程,并且该方法再次被调用到Read()另一次 我的期望是后续的Read()调用,当没有数据在他的管道中时,因为消息完成它会阻止对Read()的调用,并且一旦数据可用,Iscomplete属性将变为false,直到所有数据都被读出。 在我的代码中,在随后的Read()调用中,它不会阻塞。读取只返回0个字节并继续。
这来自https://msdn.microsoft.com/en-us/library/system.io.pipes.pipestream.read(v=vs.110).aspx

  

调用Read方法块直到读取计数字节或结束   到达流。有关异步读取操作,请参阅   BeginRead和EndRead。

另外使用本教程https://dotnetcodr.com/2015/06/23/basics-of-working-with-pipes-in-c-net-part-4-basic-conversation-with-messages/作为示例,并将管道更改为 PipeOption.Asynchromous ,我发现Read()方法会在数据可用之前进行阻塞。 顺便说一句,我认为我可以通过定期用读数轮询管道来使其工作,但如果我不确定发生了什么,我对使用该方法感到惶恐不安。 这是我的代码的骨架。

void pipeServerMethod()
{
         using (NamedPipeServerStream namedPipeServer = new NamedPipeServerStream(pipeName, /* "test-pipe"*/ PipeDirection.InOut,
                1, PipeTransmissionMode.Message, PipeOptions.Asynchronous))
            {

                var asynchResult = namedPipeServer.BeginWaitForConnection(null, null);

                if (asynchResult.AsyncWaitHandle.WaitOne(maxWait))
                {
                    namedPipeServer.EndWaitForConnection(asynchResult);



                    while (remainingAttemps > 0)
                    {

                        newInput = readMessage(namedPipeServer);

                        processReceivePipeInput(newInput, mType, allReadsComplete);


                    }
                }
    }
}


public static string readMessage(NamedPipeServerStream namedPipeServer)
    {

        int readVals; 
        string completedLine = null;
        string messageChunk = string.Empty;
        byte[] messageBuffer = new byte[30];
        do
        {

            readVals = namedPipeServer.Read(messageBuffer, 0, messageBuffer.Length);
            messageChunk = Encoding.ASCII.GetString(messageBuffer);
            completedLine = completedLine + messageChunk;
            //messageBuilder.Append(messageChunk);
            messageBuffer = new byte[messageBuffer.Length];
        }
        while (!pipetimerExpired && !namedPipeServer.IsMessageComplete);


        return completedLine;

    }

0 个答案:

没有答案