为啥线程在进程间通信期间会破坏命名管道?
Posted
技术标签:
【中文标题】为啥线程在进程间通信期间会破坏命名管道?【英文标题】:Why Does Threading Break Named Pipes During Inter-Processing Communications?为什么线程在进程间通信期间会破坏命名管道? 【发布时间】:2013-10-26 10:26:37 【问题描述】:我正在尝试为命名管道流编写一个示例 C# 程序。我创建了两个可执行文件,一个用于服务器,另一个用于客户端。请在下面检查我的代码。这两个应用程序有时正常工作,有时客户端应用程序无任何原因或异常关闭,导致服务器应用程序中的 Pipe is broken 异常。我认为,在这种情况下,这些进程是不同步的,特别是当我在它们的代码中放置一些延迟时,例如调试模式延迟。为什么当服务器仍在等待 PipeDrain (pipeServer.WaitForPipeDrain()) 时,客户端进程突然关闭?
感谢您的帮助。
服务器:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO.Pipes;
using System.IO;
using System.Threading;
namespace NamedPipeServer
class NamedPipeServerClass
static void Main(string[] args)
NamedPipeServerStream pipeServer = new NamedPipeServerStream("namedPipe", PipeDirection.InOut, 4);
StreamReader SR = new StreamReader(pipeServer);
StreamWriter SW = new StreamWriter(pipeServer);
pipeServer.WaitForConnection();
string temp;
try
SW.WriteLine("Waiting");
SW.Flush();
pipeServer.WaitForPipeDrain();
temp = SR.ReadLine();
Console.WriteLine(temp + '\n');
SW.WriteLine("Hello");
SW.Flush();
pipeServer.WaitForPipeDrain();
temp = SR.ReadLine();
Console.WriteLine(temp + '\n');
SW.WriteLine("How are you?");
SW.Flush();
pipeServer.WaitForPipeDrain();
temp = SR.ReadLine();
Console.WriteLine(temp + '\n');
SW.WriteLine("GoodBye");
SW.Flush();
pipeServer.WaitForPipeDrain();
temp = SR.ReadLine();
Console.WriteLine(temp + '\n');
catch (Exception ex)
throw ex;
finally
pipeServer.WaitForPipeDrain();
if (pipeServer.IsConnected)
pipeServer.Disconnect();
Console.WriteLine("Server: Press any key to exit...");
Console.ReadLine();
客户:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO.Pipes;
using System.IO;
using System.Threading;
namespace NamedPipeClient
class NamedPipeClientClass
static NamedPipeClientStream pipeClient;
static StreamReader SR;
static StreamWriter SW;
static Thread Conversation = new Thread(new ThreadStart(Con_function));
static bool HandShake_Ok = false;
static void Main(string[] args)
pipeClient = new NamedPipeClientStream(".", "namedPipe", PipeDirection.InOut, PipeOptions.None);
if (pipeClient.IsConnected != true)
pipeClient.Connect();
SR = new StreamReader(pipeClient);
SW = new StreamWriter(pipeClient);
Conversation.Name = "ConversationThread";
Conversation.IsBackground = true;
Conversation.Start();
static void Con_function()
string temp;
while (true)
try
temp = SR.ReadLine();
catch (Exception ex)
throw ex;
if (temp == "Waiting")
HandShake_Ok = true;
try
SW.WriteLine("Welcome");
SW.Flush();
catch (Exception ex)
throw ex;
else if (HandShake_Ok && temp == "Hello")
try
SW.WriteLine("Hi");
SW.Flush();
catch (Exception ex)
throw ex;
else if (HandShake_Ok && temp == "How are you?")
try
SW.WriteLine("I am fine");
SW.Flush();
catch (Exception ex)
throw ex;
else if (HandShake_Ok && temp == "GoodBye")
try
HandShake_Ok = false;
SW.WriteLine("Good bye :)");
SW.Flush();
catch (Exception ex)
throw ex;
更新:在客户端,写入和读取管道是在一个线程中完成的,称为Conversation。如果我删除这个线程并将所有的文字和读数带入 Main 函数,问题将得到解决。为什么线程对进程间管道通信有这样的影响?
【问题讨论】:
【参考方案1】:我相信您在这里遇到的情况是因为Conversation.IsBackground = true;
客户端应用程序不会在退出之前等待对话线程完成
试试:
Conversation.Name = "ConversationThread";
Conversation.IsBackground = true;
Conversation.Start();
Conversation.Join();
Conversation.Join();
阻止调用线程执行,直到线程对象终止
请参阅 MSDN 上的 Thread.Join Method 和 Thread.IsBackground Property
【讨论】:
以上是关于为啥线程在进程间通信期间会破坏命名管道?的主要内容,如果未能解决你的问题,请参考以下文章