Многопоточный NamePipeServer в C # - PullRequest
       33

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

15 голосов
/ 31 декабря 2010

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

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

Ответы [ 3 ]

25 голосов
/ 20 февраля 2011

Вы можете написать многопоточный конвейерный сервер, многократно создав 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
            }
        }
20 голосов
/ 03 января 2011

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

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

0 голосов
/ 31 декабря 2010

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

...