我正在使用这篇文章中的代码,唯一的区别是,在NamedPipeServerStream构造函数中,maxNumberOfServerInstances被设置为-1(具有相同管道名称的服务器实例数量仅受系统资源限制)。
异步监听方法[监听服务器类]:
我有两个WinForms应用程序:服务器只有一个“Listen”按钮(单击会调用Listen方法),客户端有一个文本框用于输入文本和一个“Send”按钮(单击会调用Send方法)。
我做了以下操作:
1. 启动多个服务器应用程序(结果是创建了具有相同管道名称的多个NamedPipeServerStream实例)。
2. 在它们中的每一个上单击“Listen”按钮。
3. 启动客户端应用程序。
4. 单击“Send”按钮。
这将导致仅一个服务器应用程序接收到消息(那个首先单击了Listen按钮的应用程序)。如果我再次单击“Send”按钮,则消息将被第二个单击的服务器应用程序接收。因此,实例按照在它们上按下Listen按钮的顺序接收消息,并在循环中重复(但我不能百分之百地确定在所有条件下这种顺序都是相同的)。
这种行为对我来说很奇怪:我原以为消息会同时被所有实例接收到。
谁能解释一下为什么会出现这种情况?
如何通过单击一个Send按钮将消息传递给所有实例?
class PipeServer
{
string _pipeName;
public void Listen(string PipeName)
{
try
{
// Set to class level var so we can re-use in the async callback method
_pipeName = PipeName;
// Create the new async pipe
NamedPipeServerStream pipeServer = new NamedPipeServerStream(PipeName,
PipeDirection.In, -1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous);
// Wait for a connection
pipeServer.BeginWaitForConnection
(new AsyncCallback(WaitForConnectionCallBack), pipeServer);
}
catch (Exception oEX)
{ ... }
}
private void WaitForConnectionCallBack(IAsyncResult iar)
{
try
{
// Get the pipe
NamedPipeServerStream pipeServer = (NamedPipeServerStream)iar.AsyncState;
// End waiting for the connection
pipeServer.EndWaitForConnection(iar);
// Read the incoming message
byte[] buffer = new byte[255];
pipeServer.Read(buffer, 0, 255);
// Convert byte buffer to string
string stringData = Encoding.UTF8.GetString(buffer, 0, buffer.Length);
...
// Kill original sever and create new wait server
pipeServer.Close();
pipeServer = null;
pipeServer = new NamedPipeServerStream(_pipeName, PipeDirection.In,
-1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous);
// Recursively wait for the connection again and again....
pipeServer.BeginWaitForConnection(
new AsyncCallback(WaitForConnectionCallBack), pipeServer);
}
catch
{ ... }
}
}
异步发送方法 [PipeClient 类]
class PipeClient
{
public void Send(string SendStr, string PipeName, int TimeOut = 1000)
{
try
{
NamedPipeClientStream pipeStream = new NamedPipeClientStream
(".", PipeName, PipeDirection.Out, PipeOptions.Asynchronous);
// The connect function will indefinitely wait for the pipe to become available
// If that is not acceptable specify a maximum waiting time (in ms)
pipeStream.Connect(TimeOut);
byte[] _buffer = Encoding.UTF8.GetBytes(SendStr);
pipeStream.BeginWrite
(_buffer, 0, _buffer.Length, new AsyncCallback(AsyncSend), pipeStream);
}
catch (TimeoutException oEX)
{ ... }
}
private void AsyncSend(IAsyncResult iar)
{
try
{
// Get the pipe
NamedPipeClientStream pipeStream = (NamedPipeClientStream)iar.AsyncState;
// End the write
pipeStream.EndWrite(iar);
pipeStream.Flush();
pipeStream.Close();
pipeStream.Dispose();
}
catch (Exception oEX)
{ ... }
}
}
我有两个WinForms应用程序:服务器只有一个“Listen”按钮(单击会调用Listen方法),客户端有一个文本框用于输入文本和一个“Send”按钮(单击会调用Send方法)。
我做了以下操作:
1. 启动多个服务器应用程序(结果是创建了具有相同管道名称的多个NamedPipeServerStream实例)。
2. 在它们中的每一个上单击“Listen”按钮。
3. 启动客户端应用程序。
4. 单击“Send”按钮。
这将导致仅一个服务器应用程序接收到消息(那个首先单击了Listen按钮的应用程序)。如果我再次单击“Send”按钮,则消息将被第二个单击的服务器应用程序接收。因此,实例按照在它们上按下Listen按钮的顺序接收消息,并在循环中重复(但我不能百分之百地确定在所有条件下这种顺序都是相同的)。
这种行为对我来说很奇怪:我原以为消息会同时被所有实例接收到。
谁能解释一下为什么会出现这种情况?
如何通过单击一个Send按钮将消息传递给所有实例?
pipeServer = null;
逻辑是为了“帮助”垃圾收集器。然而,由于它实现了IDisposable接口,使用“using”块可能更有用。 - RonnBlack