C# 检查NamedPipeServerStream是否在客户端启动的方法

C# 检查NamedPipeServerStream是否在客户端启动的方法,c#,pipe,namedpipeserverstream,C#,Pipe,Namedpipeserverstream,我有一个使用NamedPipeClientStream的客户端和一个使用NamedPipeServerStream的服务器 客户机可能在服务器之前启动,当它调用clientStream.Connect(超时)时,我得到了预期的TimeoutException 在调用Connect之前,是否有任何方法可以检查是否有NamedPipeServerStream正在侦听以防止出现异常?我建议您使用EventWaitHandle。在所有客户端上,调用WaitOne(),在服务器上,打开流后,调用Set()

我有一个使用NamedPipeClientStream的客户端和一个使用NamedPipeServerStream的服务器

客户机可能在服务器之前启动,当它调用clientStream.Connect(超时)时,我得到了预期的TimeoutException


在调用Connect之前,是否有任何方法可以检查是否有NamedPipeServerStream正在侦听以防止出现异常?

我建议您使用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远程处理wich。此外,许多人(不包括我)认为它已经过时了,至少对于IPC通信来说,这是非常体面的。这将为您提供自由度和可扩展性(也许有一天您需要您的客户机能够驻留在其他机器上,并且您必须从IPC切换到LAN通信,甚至在WAN/internet中)。

仅使用
NamedPipeClientStream无法检查这一点。但是,您可以像这样使用
互斥

// 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被打开


您还可以将异常作为一种解决方法。

如果五年后有人碰到这个问题,这可能会有所帮助:

var isPipeRunning = Directory.GetFiles( @"\\.\pipe\" ).Contains( $"\\.\pipe\{pipeName}" )

EventWaitHandles
不能跨进程边界工作。您非常确定吗?@vidstige有可能做到这一点,这里有一个创建跨进程EventWaitHandle的示例:@GeorgeLica:谢谢,我认为等待信号是科学的。。。。但是,如果服务器在创建客户机之前启动,信号在客户机注册到该信号之前设置(在创建客户机实例之前),会发生什么情况呢@Joseph我看没问题,你是服务器你的工作是等待来电。你打开管道,发出“我准备好了”的信号,然后你就等着。客户端最终将调用“waitone”,但他不会等待,因为eventwaithandle已处于“Set”模式。谢谢,这是一种非常简单直接的检查方式。