我只是想了解 C# 中的管道。 我有一个简单的 LinqPad 脚本: 如果我运行上面的代码,我会得到以下输出: 所以对client.Write的第二次调用client.Write永远阻塞。 有人可以解释一下为什么第二次调用 write(在同一线程中)会导致管道永远阻塞? 谢谢 ...
提示:本站收集StackOverFlow近2千万问答,支持中英文搜索,鼠标放在语句上弹窗显示对应的参考中文或英文, 本站还提供 中文繁体 英文版本 中英对照 版本,有任何建议请联系yoyou2525@163.com。
我正在尝试开发两个应用程序,它们在运行时通过命名管道相互通信,服务器应用程序创建两个管道,一个用于向客户端发送数据,另一个用于从中接收数据。
使用Task在另一个线程中处理写入和读取操作,在创建管道或连接它们时没有问题。
当客户端尝试在管道中写入数据时出现问题,一旦调用Write方法,执行就会停止。
//Server code
//NamedPipesManager is a class created by me.
while (!TasksStopper.IsCancellationRequested)
{
if (!NamedPipesManager.IsConnected(OutPipe) & !NamedPipesManager.IsConnected(InPipe))
{
OutPipe.WaitForConnection();
InPipe.WaitForConnection();
}
CanReceiveMessages.WaitOne(); //The server start reading data only when signaled by the client, so that there is always data to read.
MessagesSemaphore.WaitOne(); //The methods of the class can be run only by one thread at a time, a Semaphore is used to regulate access.
NamedPipesManager.ReceiveMessage(InPipe, out MessageReceived.MessageType, out MessageReceived.Response);
if (MessageReceived.MessageType == NamedPipesManager.MESSAGES.CUSTOM_PROJECT_PATH_REQUEST)
{
MessagesSemaphore.WaitOne();
NamedPipesManager.SendMessage(OutPipe, NamedPipesManager.MESSAGES.CUSTOM_PROJECT_PATH_REQUEST, Convert.ToString(CustomProjectsPath));
}
else if (MessageReceived.MessageType == NamedPipesManager.MESSAGES.DEFAULT_PROJECTS_PATH_REQUEST)
{
MessagesSemaphore.WaitOne();
NamedPipesManager.SendMessage(OutPipe, NamedPipesManager.MESSAGES.DEFAULT_PROJECTS_PATH_REQUEST, DefaultProjectsPath);
}
}
if (NamedPipesManager.IsConnected(OutPipe))
{
MessagesSemaphore.WaitOne();
NamedPipesManager.SendMessage(OutPipe, NamedPipesManager.MESSAGES.DISCONNECT, null);
OutPipe.WaitForPipeDrain();
}
//Client code
NamedPipeClientStream HubInPipe = null;
NamedPipeClientStream HubOutPipe = null;
while (!TasksStopper.IsCancellationRequested)
{
HubInPipe = NamedPipesManager.ConnectToNamedPipe(null, "ProjectExchangeAppOutPipe", NamedPipesManager.PIPE_DIRECTION.IN);
HubInPipe.ReadMode = PipeTransmissionMode.Message;
HubOutPipe = NamedPipesManager.ConnectToNamedPipe(null, "ProjectExchangeAppInPipe", NamedPipesManager.PIPE_DIRECTION.OUT);
HubOutPipe.ReadMode = PipeTransmissionMode.Message;
PipesConnectedEvent.Set();
SendMessageEvent.WaitOne();
MessagesSemaphore.WaitOne();
NamedPipesManager.SendMessage(HubOutPipe, MessageType, MessageToSend);
HubWaitHandle.Set();
MessagesSemaphore.WaitOne();
NamedPipesManager.ReceiveMessage(HubInPipe, out ReceivedMessage.MessageType, out ReceivedMessage.Response);
if (ReceivedMessage.MessageType == NamedPipesManager.MESSAGES.CUSTOM_PROJECT_PATH_REQUEST || ReceivedMessage.MessageType == NamedPipesManager.MESSAGES.DEFAULT_PROJECTS_PATH_REQUEST)
{
ReceivedMessages.Add(ReceivedMessage);
MessageReceivedEvent.Set();
}
else if (ReceivedMessage.MessageType == NamedPipesManager.MESSAGES.SETTINGS_PROFILE_CHANGED)
{
DialogResult result = MessageBox.Show("...", "Avviso", MessageBoxButtons.YesNo, MessageBoxIcon.Warning);
if (result == DialogResult.Yes)
{
ProfileName = ReceivedMessage.Response;
}
}
else if (ReceivedMessage.MessageType == NamedPipesManager.MESSAGES.DISCONNECT)
{
NamedPipesManager.ClosePipe(HubInPipe);
NamedPipesManager.ClosePipe(HubOutPipe);
}
}
if (NamedPipesManager.IsConnected(HubInPipe) & NamedPipesManager.IsConnected(HubOutPipe))
{
NamedPipesManager.ClosePipe(HubInPipe);
NamedPipesManager.ClosePipe(HubOutPipe);
}
else if (NamedPipesManager.IsConnected(HubInPipe) & !NamedPipesManager.IsConnected(HubOutPipe))
{
NamedPipesManager.ClosePipe(HubInPipe);
}
else if (!NamedPipesManager.IsConnected(HubInPipe) & NamedPipesManager.IsConnected(HubOutPipe))
{
NamedPipesManager.ClosePipe(HubOutPipe);
}
//SendMessage method of NamedPipesManager class.
if (Message != null)
{
byte[] Buffer = Encoding.Default.GetBytes(MessageType.ToString("D") + " " + Message);
Pipe.Write(Buffer, 0, Buffer.Length); //L'esecuzione si blocca qui.
}
else
{
byte[] Buffer = Encoding.Default.GetBytes(MessageType.ToString("D"));
Pipe.Write(Buffer, 0, Buffer.Length); //L'esecuzione si blocca qui.
}
Semaphore.Release();
//ReceiveMessage method of NamedPipesManager class
MessageType = MESSAGES.NONE;
Message = null;
System.Diagnostics.Debugger.Break();
StringBuilder sb = new StringBuilder();
byte[] Buffer = new byte[10];
string Chunk = string.Empty;
while (Pipe.IsConnected)
{
int BytesRead = Pipe.Read(Buffer, 0, Buffer.Length);
do
{
Chunk = Encoding.Default.GetString(Buffer);
sb.Append(Chunk);
Buffer = new byte[10];
}
while (!Pipe.IsMessageComplete);
string MessageReceived = sb.ToString();
MessageType = (MESSAGES)Convert.ToInt32(MessageReceived[0].ToString());
if (MessageReceived.Length > 1)
{
Message = MessageReceived.Substring(3);
}
}
Semaphore.Release();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.