命名管道应用程序在向NamedPipeServerStream发送请求后冻结

时间:2013-04-30 11:12:14

标签: c# c#-4.0 named-pipes

我编写了一些代码,使用命名管道将字符串从一个应用程序发送到另一个应用程序。它工作正常,但是当客户端尝试第二次发送到服务器应用程序时,它会在尝试连接到客户端时冻结。

服务器代码是:

static void StartServer()
{
   Task.Factory.StartNew(() =>
   {
      var server = new NamedPipeServerStream("MyPipe");
      server.WaitForConnection();
      StreamReader reader = new StreamReader(server);

      while (true)
      {
         var line = reader.ReadLine();

         if (line != null)
         {
            System.Windows.Forms.MessageBox.Show("Data: : " + line);
         }
      }
   });
}

客户端代码是:

private void Test()
{
    using (var client = new NamedPipeClientStream("MyPipe"))
    {
        client.Connect();
        StreamWriter writer = new StreamWriter(client);

        writer.WriteLine("INCOMING:1234567");
        writer.Flush();
        client.Dispose();
    }
}

通过跟踪代码,我可以看到服务器代码中的循环不断检查正在读入的任何行但没有找到任何行。当第二次调用client.Connect()方法时,客户端挂在Test()调用上。没有例外。

谁能看到我出错的地方?

2 个答案:

答案 0 :(得分:1)

您的服务器保持连接到用于发送第一个字符串的第一个管道实例。

但是,您的客户端在每次测试后都会处理其管道实例,因此第二个测试会创建并尝试连接新的管道实例,但服务器不再侦听,因此Connect调用阻塞等待服务器。 / p>

您需要:

  1. 使您的服务器成为多线程,以便在为已连接的实例提供服务时继续侦听;或
  2. 重构您的客户端,使其连接一次,然后重新使用该连接的实例。

答案 1 :(得分:0)

继@Chris Dickson回答后,我用以下代码解决了我的问题:

Task.Factory.StartNew(() =>
{
    var server = new NamedPipeServerStream("MyPipe", PipeDirection.InOut, 1, PipeTransmissionMode.Message, PipeOptions.Asynchronous);

    StreamReader reader = new StreamReader(server);    
    Boolean connectedOrWaiting = false;

    while (true)
    {

        if (!connectedOrWaiting)
        {
            server.BeginWaitForConnection((a) => { server.EndWaitForConnection(a); }, null);    
            connectedOrWaiting = true;
        }

        if (server.IsConnected)
        {
            var line = reader.ReadLine();

            if (line != null)
                 System.Windows.Forms.MessageBox.Show("Data: : " + line);

            server.Disconnect();    
            connectedOrWaiting = false;
        }                    
    }
});