I have a client using NamedPipeClientStream and a server using NamedPipeServerStream.
The client may start before the server, and when it call clientStream.Connect(timeout) i get TimeoutException as expected.
Is there any way I can check if there is a NamedPipeServerStream listening before calling the Connect to prevent an exception?
If someone bumps into this question five years later, this might be helpful:
var isPipeRunning = Directory.GetFiles( @"\\.\pipe\" ).Contains( $"\\.\pipe\{pipeName}" )
I suggest you should use an EventWaitHandle. On all clients, call WaitOne () and on server after opening the stream, call Set ().
So, on "server" side, write this:
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 ();
On client side, write something like this:
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 ();
There remains just a few situations to handle:
1) The pipe can't be opened on server becase there is already an opened pipe with the same name (will throw an exception).
2) You successfully opened the pipe, you notified clients that you are ready but after that, a milisecond after, the server crushes from some unexpected reason and the client cannot reach the server.
3) User rights problems
In all these situations, you should handle these exceptions using a try / catch and normally, if all goes well, this code will ensure that the client will NOT try to connect before the server successfully opened the pipe.
Anyway, I suggest using a more advanced technique for making IPC through Named Pipes such as using WCF or even .NET Remoting wich besides the fact that it's somehow considered obsolete by many (don't include me) is very decent at least for IPC communication. This will give you the freedom and scalability (maybe one day you will need your clients to be able to reside on other machines, and you will have to switch from IPC to a LAN communication or even in WAN / internet).
There is no way to check this only using a NamedPipeClientStream
. However, you can use a Mutex
like so
// 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();
You will probably want to wrap the Close
calls in a try-finally block to make sure it always closes. In the client you can use a different timeout to actually wait for the NamedPipe to be opened.
You can also catch the exception as a work around.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With