【发布时间】:2011-05-28 05:42:27
【问题描述】:
我有一个托管自定义用户控件的 Windows 窗体。此用户控件启动一个单独的进程 (.exe),该进程创建并初始化 NamedPipeServerStream。一旦进程初始化了 NamedPipeServerStream,用户控件将作为 NamedPipeClientStream 连接到它。
这一切都很好。
在 Windows 窗体上,我有一个名为“检查更新”的按钮。当按下此按钮时,NamedPipeClientStream 将向服务器发送一条消息,服务器对此作出响应,消息框显示“我已被告知检查更新”。所以我可以告诉这个客户端 > 服务器通信工作正常。
这就是问题所在。然后服务器应该向客户端发送一条 BACK 消息,告诉它它现在正在检查更新(因此用户控件可以在服务器接收到它的命令后更新它的状态)。但每当这种情况发生时,一切都会锁定。
现在我假设这是因为我试图同时读取和写入命名管道?
以下是来自服务器和客户端的一些代码 sn-ps。 (这两个 sn-ps 在各自进程中的单独线程中运行,以免阻塞 UI)
GUpdater(命名管道服务器):
private void WaitForClientCommands()
{
// Wait for a connection from a Named Pipe Client (The GUpControl)
pipeStream.WaitForConnection();
pipeConnected = true;
// Create a StreamWriter/StreamReader so we can write/read to the Named Pipe
pipeStreamWriter = new StreamWriter(pipeStream) { AutoFlush = true };
pipeStreamReader = new StreamReader(pipeStream);
// Now that we have a connection, start reading in messages and processing them
while (true)
{
// Skip this time if we are currently writing to the pipe
if(isWritingToPipe) continue;
var message = pipeStreamReader.ReadLine();
if (message == null)
{
// We don't want to hog up all the CPU time, so if no message was reaceived this time, wait for half a second
Thread.Sleep(500);
continue;
}
switch(message)
{
case "CheckForUpdates":
//MessageBox.Show("Told to check for updates");
SendMessageToClient("Checking For Updates, Woot!");
break;
case "DownloadUpdate":
MessageBox.Show("Told to download update");
break;
case "ApplyUpdate":
MessageBox.Show("Told to apply update");
break;
}
}
}
GUpControl(命名管道客户端):
private void WaitForServerCommands()
{
if(!pipeConnected) return;
// Now that we have a connection, start reading in messages and processing them
while (true)
{
// Skip this time if we are currently writing to the pipe
if (isWritingToPipe) continue;
// Attempt to read a line from the pipe
var message = pipeStreamReader.ReadLine();
if (message == null)
{
// We don't want to hog up all the CPU time, so if no message was reaceived this time, wait for half a second
Thread.Sleep(500);
continue;
}
MessageBox.Show("I got a message from the server!!\r\n" + message);
}
}
下面的sn-p是负责从各个组件写入Client/Server的方法。 (唯一的区别在于名称,即SendMessageToClient和SendMessageToServer)
private void SendMessageToServer(string message)
{
if(pipeConnected)
{
isWritingToPipe = true;
pipeStreamWriter.WriteLine(message);
isWritingToPipe = false;
}
}
isWritingToPipe 变量是一个简单的布尔值,当相应的进程尝试写入命名管道时为真。这是我解决问题的初步尝试。
非常感谢任何帮助!
【问题讨论】:
-
任何完整的源代码示例?
标签: c# named-pipes