Многопоточный сервер NamePipeServer в C#

Привет
Я хочу использовать NamedPipeServerStream что является новым из .NET 3.5 для связи namedpipe. Я хочу написать многопоточный сервер каналов. она обрабатывается по умолчанию или я должен написать код для этого. мой трубопроводный сервер должен обрабатывать несколько запросов одновременно

любое решение или код ?

3 ответов


каждый экземпляр NamedPipeServerStream является реализацией потока, обертывающей дескриптор в экземпляр именованного канала. Вы можете (и многопоточный сервер каналов) иметь несколько экземпляров NamedPipeServerStream для одного и того же именованного канала: каждый из них обертывает дескриптор в другой экземпляр именованного канала, обслуживая другой клиент. Экземпляры именованных каналов (даже для одного канала) хранятся отдельно операционной системой, поэтому нет необходимости в явном кодировании для сохранения каждого клиента связь с сервером отдельная.

то, что вам нужно явно кодировать, - это потоковая модель для сервера. Самый простой подход к многопоточности сервера объясняется в это так ответ, который включает в себя шаблон псевдо-кода. Более масштабируемые реализации, если необходимо поддерживать большое количество параллельных вызовов, будут использовать пул потоков и асинхронные методы вместо создания выделенного потока для каждого соединения.


вы можете написать многопоточный трубопроводный сервер, повторно создавая NamedPipeServerStream и ожидая одного соединения, а затем создавая поток для этого экземпляра NamedPipeServerStream.

вы можете иметь только 254 параллельных клиентов, хотя в соответствии с документацией .NET MSDN, связанной ниже. Для Win32 API, хотя вы можете передать специальное значение, чтобы получить неограниченное на основе системных ресурсов. Кажется, документация MSDN неверна, как указано ниже.

приведенный ниже код не тестируется, поэтому, пожалуйста, не просто скопируйте и вставьте для использования в производстве без тестирования:

    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
            }
        }

NamedPipeServerStream-это соединение точка-точка. Вы должны синхронизировать вызовы самостоятельно - например, вызовы, записанные в очередь, и ваш сервер читает из синхронизированной очереди и делает вызовы.