我有一个使用 NamedPipeClientStream 的客户端和一个使用 NamedPipeServerStream 的服务器。
客户端可能在服务器之前启动,当它调用 clientStream.Connect(timeout) 时,我得到了预期的 TimeoutException。
有什么方法可以在调用 Connect 之前检查是否有 NamedPipeServerStream 监听以防止异常?
我有一个使用 NamedPipeClientStream 的客户端和一个使用 NamedPipeServerStream 的服务器。
客户端可能在服务器之前启动,当它调用 clientStream.Connect(timeout) 时,我得到了预期的 TimeoutException。
有什么方法可以在调用 Connect 之前检查是否有 NamedPipeServerStream 监听以防止异常?
如果五年后有人碰到这个问题,这可能会有所帮助:
var isPipeRunning = Directory.GetFiles( @"\\.\pipe\" ).Contains( $"\\.\pipe\{pipeName}" )
我建议你应该使用 EventWaitHandle。在所有客户端上,调用 WaitOne(),在服务器上打开流后,调用 Set()。
所以,在“服务器”端,这样写:
EventWaitHandle handle = new EventWaitHandle(false, EventResetMode.ManualReset, String.Format(@"Global\{0}", "SERVER_OPENED_HANDLE"));
OpenStream (); // inside this method you would have code that opens your named pipe for incomming messages
// finally, signal that you are done
handle.Set ();
在客户端,编写如下内容:
EventWaitHandle handle = new EventWaitHandle(false, EventResetMode.ManualReset, String.Format(@"Global\{0}", "SERVER_OPENED_HANDLE"));
// here your thread will sleep until the server calls "Set"
handle.WaitOne ();
// then you can safelly connect to the server here
ConnectToServer ();
剩下的只有几种情况需要处理:
1)无法在服务器上打开管道,因为已经有一个同名的打开管道(将抛出异常)。
2)您成功打开管道,通知客户端您已准备好,但在那之后,一毫秒后,服务器因某种意外原因崩溃,客户端无法访问服务器。
3) 用户权限问题
在所有这些情况下,您应该使用 try/catch 处理这些异常,通常,如果一切顺利,此代码将确保客户端在服务器成功打开管道之前不会尝试连接。
无论如何,我建议使用更先进的技术通过命名管道制作 IPC,例如使用 WCF 甚至 .NET Remoting,除了它在某种程度上被许多人(不包括我)认为已经过时的事实至少对于 IPC 通信来说是非常不错的. 这将为您提供自由和可扩展性(也许有一天您将需要您的客户端能够驻留在其他机器上,并且您将不得不从 IPC 切换到 LAN 通信甚至是 WAN / Internet)。
无法仅使用NamedPipeClientStream
. 但是,您可以Mutex
这样使用
// In the server
var mutex = new System.Threading.Mutex(false, "MyPipeMutex");
OpenPipeAndRunServer();
mutex.Close();
// In the client process
var mutex = new System.Threading.Mutex(false, "MyPipeMutex");
if (!mutex.WaitOne(0, false))
{
OpenPipe();
}
mutex.Close();
您可能希望将Close
调用包装在 try-finally 块中,以确保它始终关闭。在客户端中,您可以使用不同的超时来实际等待打开 NamedPipe。
您还可以捕获异常作为解决方法。