2012-05-09 15 views
9

私はクラスを持っています。例えば、 "MyComputation"は1つの長いコンストラクタで多くの計算を行います。ディスクI/Oまたはネットワーク操作なしで、それ自身で実行すると通常は約20msかかる。作業項目としてのThreadPoolにそれらをキューに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(); 
     } 
    } 

private static ManualResetEvent done_event; 

    ... 

    done_event = new ManualResetEvent(false); 

私はComputeParent約500かそこら回実行し、様々な入力パラメータのため:

done_eventは静的ManualResetEventです。だから私はたくさんのネストされたクラスを持っています。問題は、ComputeParentを実行するのにかかる時間が徐々に増加することです。各特定のComputeParentを実行するのにかかる時間には一定の変動がありますが、時間はかなり長くなります(幾何学的には、連続する各繰り返しがより長くかかる)。

非常に高い(〜300MB)が、プログラムのメモリ消費は目立って増加しません。 8つの論理コアを持つコンピュータ上で動作し、プロセッサの使用は非常にバースト的なようです。私は他に何が問題に関連しているのかは分かりません。

私はバッチファイルでComputeParentを実行する必要はありませんが、これが行われても問題は発生しないようです。

+2

TPLを使用しない理由はありますか(.NET <4)のような理由はありますか? –

+6

プロファイリングを開始する必要があります。測定することは知ることです。これは、GC活動、他のスレッド、増加する可能性があります...このコードには明らかな手掛かりはありません。 –

+2

プロファイリングを試しましたか?私もTPLの使用をお勧めします。 – Simon

答えて

3

ThreadPoolで使用可能なスレッドの数が0になり、引き続き新しい作業項目を追加すると、新しく追加された作業項目が「待機」します。これは、ComputeParentが "myComputationCall"のインスタンスを待つことを意味します。より多くのComputeParentを起動すると、それらの平均実行時間が増加します。

0

この質問は回答されました。すべてのポスターに感謝します。

同様の問題を抱える他の人にとっては、私はHenkが提案するタスク並列ライブラリを提案します。

関連する問題