我正在使用异步管道,并且在某些时候服务器和客户端都互相等待,什么也不做。这是我的代码:

服务器:

var buffer = new byte[BufferSize];
using (var server = new NamedPipeServerStream(pipeName, PipeDirection.InOut, 1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous))
{
    // Wait for client.
    Logger.Trace("Waiting for connection ...");
    var asyncResult = server.BeginWaitForConnection(a => { }, null);
     while (true)
     {
          await Task.Delay(MillisecondsDelay);
          if (asyncResult.IsCompleted) break;
      }
      server.EndWaitForConnection(asyncResult);
      Logger.Trace("Connection established.");


       using (var sr = new StreamReader(server))
       using (var sw = new StreamWriter(server))
       {
             // Send work.
             Logger.Trace("Sending operations...");
             await sw.WriteAsync(JsonConvert.SerializeObject(data));
             await sw.FlushAsync();
             server.WaitForPipeDrain();

              // Wait for response.
              var bytesRead = await server.ReadAsync(buffer, 0, buffer.Length);

       .....

客户:
        // Read data from the pipe...
 using (var client = new NamedPipeClientStream(".", pipeName, PipeDirection.InOut, PipeOptions.Asynchronous))
 {
      Logger.Trace("Connecting to server...");
      client.Connect();
      Logger.Trace("Connected.");

      using (var sr = new StreamReader(client))
      using (var sw = new StreamWriter(client))
      {
           // Read operations.
           Logger.Trace("Waiting operations...");
           var text = await sr.ReadToEndAsync();
       .....

我采取的日志是这些:
2016-10-04 16:09:51.5375 => (TRACE) | MyController.Execute : Waiting for connection ... |
2016-10-04 16:09:52.0706 => (TRACE) | MyController+<Execute>d__5.MoveNext : Connection established. |
2016-10-04 16:09:52.0706 => (TRACE) | MyController+<Execute>d__5.MoveNext : Sending operations... |

和 :
2016-10-04 16:09:51.8486 => (TRACE) | EXE.Program.Process : Connecting to server... |
2016-10-04 16:09:51.8696 => (TRACE) | EXE.Program.Process : Connected. |
2016-10-04 16:09:51.8696 => (TRACE) | EXE.Program.Process : Waiting operations... |

然后什么都没有!

在那之后,它似乎陷入僵局。

我想我应该在服务器或客户端每次写入后使用 WaitForPipeDrain() 并且我这样做,但它似乎没有帮助。

客户端读取操作永远不会返回。

任何人的想法?

最佳答案

我认为问题出在 ReadToEndAsync 方法中。 StreamReader 无法确定传输结束。例如,它可能是一个缓慢的连接并且只发送了一半的数据。通常在这些情况下,您需要提出自己的“协议(protocol)”来发送数据。有多种方法,这里有几个:

  • 等待终止符。很多次我都看到 ASCII 字符 4 用于此,因为它表示“EOT”( end of transmission )。但是,这是基于这样的假设,即您的消息不仅仅是可能包含该字符的二进制数据流。您可以将终止符改为一个序列,即一些几乎永远不会出现在流中的字符。
  • 使用您将要发送的数据长度作为消息前缀。例如,前 4 个字节是 总是 的长度,抓取之后,您现在知道要读取多少。
  • 关于C# 异步命名管道永远等待,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/39853664/

    10-11 21:59