Multithreaded NamePipeServer in C#

Hi
I want to use NamedPipeServerStream which is new from .NET 3.5 for namedpipe communication. I want to write multi-threaded pipe server. is it handled by default or I should write code for that. my pipe server should handle multiple request at a time

any solution or code ?


Solution 1:

You can write a multi threaded pipe server by repeatedly creating a NamedPipeServerStream and waiting for one connection, then spawning a thread for that instance of NamedPipeServerStream.

You can only have 254 concurrent clients though according to the .NET MSDN documentation linked below. For Win32 APIs though you can pass a special value to get unlimited based on system resources. It seems the MSDN documentation is wrong as noted below.

The below code is not tested so please do not simply copy and paste for production use without testing:

    public class PipeServer
    {
        bool running;
        Thread runningThread;
        EventWaitHandle terminateHandle = new EventWaitHandle(false, EventResetMode.AutoReset);
        public string PipeName { get; set; }

        void ServerLoop()
        {
            while (running)
            {
                ProcessNextClient();
            }

            terminateHandle.Set();
        }

        public void Run()
        {
            running = true;
            runningThread = new Thread(ServerLoop);
            runningThread.Start();
        }

        public void Stop()
        {
            running = false;
            terminateHandle.WaitOne();
        }

        public virtual string ProcessRequest(string message)
        {
            return "";
        }

        public void ProcessClientThread(object o)
        {
            NamedPipeServerStream pipeStream = (NamedPipeServerStream)o;

            //TODO FOR YOU: Write code for handling pipe client here

            pipeStream.Close();
            pipeStream.Dispose();
        }

        public void ProcessNextClient()
        {
            try
            {
                NamedPipeServerStream pipeStream = new NamedPipeServerStream(PipeName, PipeDirection.InOut, 254);
                pipeStream.WaitForConnection();

                //Spawn a new thread for each request and continue waiting
                Thread t = new Thread(ProcessClientThread);
                t.Start(pipeStream);
            }
            catch (Exception e)
            {//If there are no more avail connections (254 is in use already) then just keep looping until one is avail
            }
        }

Solution 2:

Each NamedPipeServerStream instance is a Stream implementation wrapping a handle to an instance of a named pipe. You can (and a multithreaded pipe server will) have multiple instances of NamedPipeServerStream for the same named pipe: each one wraps a handle to a different instance of the named pipe, servicing a different client. Named pipe instances (even for the same pipe) are kept separate by the operating system, so there is no need for any explicit coding to keep each client's communication with the server separate.

What you do need to code explicitly is the threading model for the server. The simplest approach to multithreading the server is explained in this SO answer, which includes a pseudo-code template. More scalable implementations, if large numbers of concurrent callers need to be supported, would use thread pooling and the asynchronous methods instead of creating a dedicated thread for each connection.