命名管道挂在读取上 [英] Named pipe hanging on read

查看:51
本文介绍了命名管道挂在读取上的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个命名管道服务器.客户端发送消息,这看起来没问题,但是服务器只是挂在 var stringData = textReader.ReadToEnd(); 行上.

I have a named pipe server. The client sends the message, which seems OK, however the server just hangs on the line var stringData = textReader.ReadToEnd();.

var namedPipeServerStream = new NamedPipeServerStream(_pipeName,
                        PipeDirection.In,
                        1,
                        PipeTransmissionMode.Byte,
                        PipeOptions.Asynchronous);

namedPipeServerStream.WaitForConnection();

using (var textReader = new StreamReader(namedPipeServerStream))
{
    var stringData = textReader.ReadToEnd();

    _callback(stringData);

    namedPipeServerStream.Flush();
    namedPipeServerStream.Close();
}

Thread.Sleep(1);

客户端看起来像这样:

public void Send(string message)
{
    var pipeStream = new NamedPipeClientStream(_serverName,
        _pipeName,
        PipeDirection.Out,
        PipeOptions.Asynchronous);

    pipeStream.Connect(_timeout);

    var buffer = UTF8.GetBytes(message);

    pipeStream.Write(buffer, 0, buffer.Length);
}

为什么挂了?

推荐答案

NamedPipe 流,就像网络流一样,没有明确的终点,它们只是暂时枯竭",这就是为什么您的 ReadToEnd 无限期调用的原因尝试读取更多数据.

NamedPipe streams, like network streams, have no definite end, they just temporarily "dry up", that's why your ReadToEnd call indefinitely tries to read more data.

但是,您可以在服务器端将 PipeTransmissionMode 更改为 Message 以使对管道的每次写入都被视为单独的消息,然后从流直到 IsMessageComplete 返回 true.例如:

However, you could change the PipeTransmissionMode to Message on the server-side to make each write to the pipe to be treated as a separate message, and then read from the stream until IsMessageComplete returns true. e.g.:

using (var namedPipeServerStream = new NamedPipeServerStream(_pipeName,
                PipeDirection.InOut,
                1,
                PipeTransmissionMode.Message,
                PipeOptions.Asynchronous))
{
    namedPipeServerStream.WaitForConnection();

    MemoryStream ms = new MemoryStream();
    byte[] buffer = new byte[0x1000];
    do { ms.Write(buffer, 0, namedPipeServerStream.Read(buffer, 0, buffer.Length)); }
    while (!namedPipeServerStream.IsMessageComplete);

    string stringData = Encoding.UTF8.GetString(ms.ToArray());
    _callback(stringData);
}

Thread.Sleep(1);

这篇关于命名管道挂在读取上的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆