有关这个问题已经有很多讨论,但他们似乎无法解释我的特定问题。使用ThreadPool而不是Thread类进行线程处理时,我遇到了严重的性能问题。
细节如下:
我建立了一个TCP服务器,当TCP服务器接受新客户端时,它会生成一个新线程来处理该客户端。非常简单,但是当服务器需要处理许多并发客户端时,它处理起来需要太长时间。对于大约35个只发送2048字节缓冲区、接收并关闭的简单客户端,需要30秒才能处理完毕。
经过多次计时,我发现ThreadPool.QueueUserWorkItem最多需要26秒。我使用它来为处理新客户端生成新线程。 将ThreadPool.QueueUserWorkItem替换为new Thread()后,我的性能提高到不到一秒。
我希望能够得到一些解释为什么会出现这种情况。
澄清: 延迟与客户端代码无关,从调用ThreadPool.QueueUserWorkItem到clientMsgHandler.HandleIncomingMsgs启动可以花费20秒。 滞后始于第一个线程,并随着测试的进行略微改善。我更感兴趣的是解释为什么会出现这种情况,而不是解决方案。 客户端确实会阻塞,但只有很短的时间。
服务器代码:
细节如下:
我建立了一个TCP服务器,当TCP服务器接受新客户端时,它会生成一个新线程来处理该客户端。非常简单,但是当服务器需要处理许多并发客户端时,它处理起来需要太长时间。对于大约35个只发送2048字节缓冲区、接收并关闭的简单客户端,需要30秒才能处理完毕。
经过多次计时,我发现ThreadPool.QueueUserWorkItem最多需要26秒。我使用它来为处理新客户端生成新线程。 将ThreadPool.QueueUserWorkItem替换为new Thread()后,我的性能提高到不到一秒。
我希望能够得到一些解释为什么会出现这种情况。
澄清: 延迟与客户端代码无关,从调用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));
}