2013-07-17 77 views
0

我有一個應用程序需要處理的消息負載(例如:每秒2000)。業務需求要求我不要立即處理消息,而是要等待2秒來處理每條消息。我現在正在做的是從每個消息的Task.Factory.StartNew中分離一個線程池中的線程,並在線程池中執行「等待2秒」的任務。問題是,當消息負載非常高時,我總是會遇到OutOfMemory異常,但根據Windows操作系統的任務管理器,內存消耗實際上並不高。但是,如果我不在線內等待,那麼一切都很好。ThreadPool線程需要等待

我的猜測是,當消息負載很高時,線程池線程不足以處理所有消息。因此越來越多的消息排隊等待處理,當隊列大小變得非常大時,會導致OOM異常。已經嘗試將ThreadPool.SetMaxThreads和ThreadPool.SetMinThreads設置爲非常高的數量,但仍然不起作用。任何建議?

的代碼看起來是這樣的:

ThreadPool.SetMaxThreads(32768, 32768); 
ThreadPool.SetMinThreads(2500, 2500); 

public void HanldeMessage(string message) 
{ 
    Task.Factory.StartNew(() => DoWork(message)) 
} 

public void DoWork(string message) 
{ 
    Thread.Sleep(2000); 
    // do some work to message 
} 
+0

可能的重複[如何將其轉換爲異步任務?](http://stackoverflow.com/questions/21800450/how-do-i-convert-this-to-an-async-task) – Noseratio

回答

2

試試這個。你需要.NET 4.5。

private static void HandleMessage(string message) 
{ 
    DoWork(message); 
} 

private static async Task DoWork(string message) 
{ 
    await Task.Delay(2000); // instead of thread.Sleep 

    // do some work... 
    Console.WriteLine(message); 
} 

而不是阻塞thread.sleep,這應該有效地返回線程到池2秒,然後返回執行。

我建議您不要屏蔽線程,特別是在處理可能需要數千人的場景時。我也建議你不要設置ThreadPool.MaxThreads/MinThreads。你在這裏經歷了很多的虐待。

每個線程佔用1MB的堆棧空間。我敢打賭,你看到OOM異常的原因是因爲你創建了太多的線程,而不是因爲排隊請求創建線程。你上面的情況很糟糕,因爲在完成所有創建線程的工作之後,它只是坐落並腐爛2秒鐘。要求進行更多的工作,並且線程池通過創建另一個線程池來幫助解決問題。隨着您期望的要求數量的增加,其只有一段時間直到記憶成爲障礙。