线程池性能极度滞后

lav*_*vuy 4 .net c# performance multithreading threadpool

关于这个问题已经有很多讨论,但它们似乎无法解释我的具体问题。当使用 ThreadPool 而不是 Thread 类进行线程处理时,我遇到了严重的性能问题。

细节:

我已经构建了一个 tcp 服务器,当 tcp 服务器接受新客户端时,它会生成一个新线程来处理该客户端。一切都相当简单,但是我的服务器需要很长时间才能处理许多并发客户端。大约 35 个简单客户端需要 30 秒,这些客户端仅发送 2048 字节缓冲区、接收它并关闭。

经过多次停留后,我发现最多ThreadPool.QueueUserWorkItem需要 26 秒。我用它来生成新线程来处理新客户端。更换后ThreadPool.QueueUserWorkItem我new Thread()的性能提高到不到一秒。

我想要一些解释为什么会发生这种情况。

澄清:

Delay与客户端代码无关,从ThreadPool.QueueUserWorkItem被调用到clientMsgHandler.HandleIncomingMsgs启动需要20秒的时间。

延迟从第一个线程开始,并且随着测试的继续而实际上略有改善。我对解决方案不太感兴趣,更感兴趣的是解释为什么会发生这种情况。客户端确实会阻塞,但时间很短。

服务器代码:

private void AddTcpClientMsgHandler(TcpClient tcpClient)
    {
        //lock so no addition of client and closure can occur concurrently
        Stopwatch watch = new Stopwatch();
        watch.Start();
        Monitor.Enter(this);
        int pWatchIdx =  watchIDX++;
        if (!isOpen)
            throw new ObjectDisposedException(ResourceAlreadyClosed);

        TcpClientMsgHandler clientMsgHandler = CreateClientHandler(tcpClient);                                         
        clientMsgHandlerManager.AddTcpClientMsgHandler(clientMsgHandler);
        //ThreadPool.QueueUserWorkItem(clientMsgHandler.HandleIncomingMsgs); takes 20 seconds to run
        Thread thread = new Thread(clientMsgHandler.HandleIncomingMsgs);
        thread.Start();
        watch.Stop();
        Monitor.Exit(this);
        Console.WriteLine(string.Format("Iteration {0} took {1} Client {2}", pWatchIdx.ToString(),watch.Elapsed, tcpClient.Client.RemoteEndPoint));

    }
Run Code Online (Sandbox Code Playgroud)

spe*_*der 5

阻塞代码是线程池的敌人。从您发布的示例中,无法判断阻塞发生在哪里,但我建议您检查代码路径以找出代码阻塞的位置。在调试器中运行服务器,直到它开始显示高延迟,然后中断执行并查看 VS 的线程面板。这将显示线程被阻塞的位置。这很可能是在同步 IO 上。考虑用异步代码替换。