【问题标题】:Multithreaded NamePipeServer in C#C# 中的多线程 NamePipeServer
【发布时间】:2011-06-02 00:32:18
【问题描述】:


我想使用 .NET 3.5 中新增的 NamedPipeServerStream 进行命名管道通信。 我想编写多线程管道服务器。它是默认处理的还是我应该为此编写代码。我的管道服务器应该一次处理多个请求

任何解决方案或代码?

【问题讨论】:

  • 从客户端到名称管道服务器的最大请求数是多少?
  • 只要管道的两端都打开,客户端可以对命名管道进行的读写次数没有限制。

标签: c# .net multithreading named-pipes


【解决方案1】:

NamedPipeServerStream 是点对点连接。您必须自己同步调用 - 例如写入队列的调用,而您的服务器从同步队列中读取并进行调用。

【讨论】:

    【解决方案2】:

    每个 NamedPipeServerStream 实例都是一个 Stream 实现,它包装了一个命名管道实例的句柄。您可以(并且多线程管道服务器将)为同一个命名管道拥有多个 NamedPipeServerStream 实例:每个实例都包装一个指向不同命名管道实例的句柄,为不同的客户端提供服务。命名管道实例(即使对于同一个管道)由操作系统分开,因此不需要任何显式编码来保持每个客户端与服务器的通信分开。

    您需要明确编码的是服务器的线程模型。在this SO answer 中解释了对服务器进行多线程处理的最简单方法,其中包括一个伪代码模板。如果需要支持大量并发调用者,更具可扩展性的实现将使用线程池和异步方法,而不是为每个连接创建专用线程。

    【讨论】:

    • 所以我们需要为每个客户端创建新的服务器流?
    【解决方案3】:

    您可以通过重复创建 NamedPipeServerStream 并等待一个连接,然后为该 NamedPipeServerStream 实例生成一个线程来编写多线程管道服务器。

    根据下面链接的 .NET MSDN 文档,您只能拥有 254 个并发客户端。对于 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
                }
            }
    

    【讨论】:

    • @Brian:为什么说“你只能有 254 个并发客户端”?默认情况下,NamedPipeServerStream 在调用 Win32 CreateNamedPipe API 时指定 PIPE_UNLIMITED_INSTANCES,Win32 文档中显示为the number of pipe instances that can be created is limited only by the availability of system resources
    • ArgumentOutOfRangeException 在 `maxNumberofServerInstances 小于 1 或大于 254 时抛出。msdn.microsoft.com/en-us/library/bb355105.aspx
    • @Brian:NamedPipeServerStream ctor 的文档位于其中。对应于PIPE_UNLIMITED_INSTANCES 的值-1 也是可接受的值。 if (((maxNumberOfServerInstances < 1) || (maxNumberOfServerInstances > 0xfe)) && (maxNumberOfServerInstances != -1)) { throw new ArgumentOutOfRangeException("maxNumberOfServerInstances", SR.GetString("ArgumentOutOfRange_MaxNumServerInstances")); }
    • 您能否提供另一个与您提到的我引用的文档相矛盾的参考资料?
    • 我在这里看到:msdn.microsoft.com/en-us/library/aa365150(v=vs.85).aspx 它谈到了基于系统资源的无限,但我想知道.NET 实现是否不同?
    猜你喜欢
    • 1970-01-01
    • 2010-12-14
    • 1970-01-01
    • 2016-07-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多