【问题标题】:Multithreaded Server implementation in C#C# 中的多线程服务器实现
【发布时间】:2013-03-26 20:01:18
【问题描述】:

我正在创建一个 Windows 服务,该服务具有一个组件,该组件侦听命名管道以与从用户空间运行的程序进行交互。我使用来自this answer 的代码作为多线程服务器实现的基础,但是我从在紧密循环中调用的 ProcessNextClient 操作中获得了强烈的代码气味,如下所示。真的没有比重复捕获 IOException 并重试更好的方法来知道何时将另一个流的开口添加到命名管道吗?

    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 直到资源可用的方法。

标签: multithreading service while-loop namedpipeserverstream


【解决方案1】:

您可以按照 WCF 来处理管道吗?您将从使用 IO 完成端口的中断驱动系统中受益,以便在应用程序中建立新连接时通知您的应用程序代码。

如果您只需将绑定从管道更改为 TCP/http 绑定,就可以在多个节点上运行您的应用程序,那么您还可以通过实施 WCF 来扩展一台机器。

An example implementation of a WCF service is here。它还展示了如何在管道或 TCP 上托管相同的服务。

【讨论】:

  • 很好的建议。提供一个简单的示例或一个链接,我会将您标记为已接受。
【解决方案2】:

在我看来,代码将位于

pipeStream.WaitForConnection();

直到检测到客户端,然后继续。我不认为它会像你描述的那样循环它,除非它被客户锤击。你总是可以添加一个断点来检查。

【讨论】:

  • 它会,直到达到服务器实例的限制。然后是一个 throw->catch 紧密循环。我想我正在寻找的是一种阻塞方式,直到至少一个现有任务/线程完成释放它对管道的控制。
  • 如果在错误捕获中添加 Thread.Sleep 会怎样?它将暂停应用程序线程以防止过多的 cpu 负载。或者您可以将请求排队。
  • Sleep 至少可以防止进程占用 CPU,但不优雅仍然存在。您能否详细说明排队请求的含义?
  • 在 .NET 中使用 try-catch 并不总是禁忌。在某些情况下这是不可避免的,特别是在处理您无法控制的事情时,例如“文件正在使用”问题或当您有客户敲击您的 Windows 服务时。在这些情况下,最好简单地使用“是否有效”阈值。通过排队,我的意思是一旦达到限制,您可以将客户端添加到队列中,然后在开始侦听新客户端之前检查队列
  • 我并不是要避免try catch,而是我要避免spinlocktight loop。如果没有打开的 NamedPipeServerStream,就没有客户端可以排队。有了一个,就不用屏蔽了。
猜你喜欢
  • 2014-02-19
  • 2021-11-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-11-04
  • 1970-01-01
相关资源
最近更新 更多