2012-05-09 47 views
9

我有一個類,說「MyComputation」,它在一個長構造函數中做了很多計算。它自己執行時通常需要大約20ms的時間運行(沒有磁盤I/O或網絡操作)。這個類的100種左右的情況下,由父類創建的,說「ComputeParent」,哪個隊列起來的線程池工作項:隨着時間的推移C#ThreadPool應用程序性能下降

ThreadPool.QueueUserWorkItem(myComputationCall, my_computation_data); 

「myComputationCall」看起來是這樣的:

public static void myComputationCall(Object my_computation_data) 
    { 
     try 
     { 
      MyDataObject data = (MyDataObject)my_computation_data; 

      var computation_run = new MyComputation(data.parameter1, data.parameter2); 

      data.result = computation_run.result; 
     } 
     finally 
     { 
      if (Interlocked.Decrement(ref num_work_items_remaining) == 0) 
       done_event.Set(); 
     } 
    } 

done_event是靜態的ManualResetEvent:

private static ManualResetEvent done_event; 

    ... 

    done_event = new ManualResetEvent(false); 

我運行ComputeParent約500左右的時間,關於各種輸入參數。所以我有很多嵌套類。問題是執行ComputeParent所花費的時間會逐漸增加。運行每個特定ComputeParent需要多長時間會有一定的變化,但時間量會相當穩定地增加(幾何上,每個連續迭代需要更長的時間)。

雖然程序的內存消耗非常高(〜300MB),但是隨着時間的推移,程序的內存消耗並不會明顯增加。它運行在具有8個邏輯內核的計算機上,處理器的使用似乎非常突兀。我不確定還有什麼可能與問題有關。

我不希望通過批處理文件運行ComputeParent,但在完成此操作時不會出現此問題。

+2

是否有任何理由(如.NET <4)不使用TPL? –

+6

你應該開始分析。度量是要知道的。它可能會增加GC活動,其他線程......在這段代碼中沒有明顯的線索。 –

+2

你有沒有試過分析它?我也推薦使用TPL。 – Simon

回答

3

如果ThreadPool中的可用線程數量變爲0,並且您繼續添加新工作項目,那麼新添加的工作項目將「等待」。這意味着您的ComputeParent將等待其「myComputationCall」的實例。開始越來越多的ComputeParent會導致它們的平均執行時間會增加。

0

此問題已回答。感謝所有的海報。

對於其他有類似問題的人,我會建議Henk建議的任務並行庫。

相關問題