關於這個問題已經有不少討論,但他們似乎無法解釋我的特殊問題。 線程使用ThreadPool而不是Thread類時,我遇到了嚴重的性能問題。線程池極端性能滯後
細節:
我建立了一個TCP服務器,當TCP服務器接受新的客戶端就產生一個新的線程來處理該客戶端。所有相當簡單,但它需要我的服務器方式太長,以處理許多併發的客戶端。約30個簡單的客戶端只需發送一個2048字節的緩衝區30秒,收到並關閉。
經過很多秒錶,我發現ThreadPool.QueueUserWorkItem
需要長達26秒。我用它來產生處理新客戶端的新線程。 將ThreadPool.QueueUserWorkItem
替換爲new Thread()
後,我的表現改善至不到一秒。
我很想解釋爲什麼會發生這種情況。
澄清:
延遲無關與客戶端的代碼,從目前直到clientMsgHandler.HandleIncomingMsgs開始20秒可以通過ThreadPool.QueueUserWorkItem被調用。
滯後從第一個線程開始,實際上隨着測試的繼續而略微提高。我對解決方案不太感興趣,並且更關心解釋爲什麼會發生這種情況。 客戶端確實阻塞,但時間很短。
服務器代碼:
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));
}
嘗試使用性能分析器,例如[Red Gate的ANTS性能分析器](http://www.red-gate.com/products/dotnet-development/ants-performance-profiler/)。 –
你可能已經沒有線程池中的線程了嗎? –
通用診斷是您的HandleIncomingMsgs()方法過長。在finally塊中不使用Monitor.Exit()是嚴重的bug。 –