大規模な並列処理のために非同期デリゲートまたはThreadPool.QueueUserWorkItemを使用しますか?

StackOverflow https://stackoverflow.com/questions/192539

質問

バッチインポートで約300,000レコードを処理する.NETアプリケーションがあり、レコードごとに数秒かかるため、これを並列化したいと思います。次のコードでは、 ProcessWithAnsycDelegates() ProcessWithThreadPool()の違いは何ですか?

public class ResultNotification
 { public EventHandler event Success;
   public EventHandler event Fail;
   internal void Notify(bool sucess) {if (success) Success(); else Fail();}
 }

public static class Processor
 { public ResultNotification ProcessWithAnsycDelegates(Record record)
    { var r = new ResultNotification();
      Func<Record,bool> processRecord=new RecordProcessor().ProcessRecord;
      processRecord.BeginInvoke
                     ( record
                      ,ar => result.Notify(processRecord.EndInvoke(ar))
                      ,null); 
      return r;    
    }

   public ResultNotification ProcessWithThreadPool(Record r)
    { var r  = new ResultNotification();
      var rp = new RecordProcessor();
      ThreadPool.QueueWorkUserItem(_=>result.Notify(rp.ProcessRecord(r)));
      return r;
    }
 }
役に立ちましたか?

解決

この場合、両者はフードの下でスレッドプールを使用するため、あまり多くありません。 QueueUserWorkItem()の方が、BeginInvokeと比べて読みやすく、何が起こっているかを確認しやすいと思います。

このリンクが役立つ場合があります。それは古い情報ですが、それでもほとんど適用可能です http://www.yoda.arachsys.com/csharp/threads/threadpool.shtml

他のヒント

質問に対する文字通りの答えは、両方ともスレッドプールを使用するということです。そのため、パフォーマンスのみが考慮される場合、違いはあまりありません。

質問が本当に最高のパフォーマンスを得ることである場合、スレッドプールの使用には問題があることを知るのに役立つかもしれません。これらは次のとおりです。

  • 作業キューの競合をロック
  • コンテキストの過度の切り替え。 2つのCPUと一連の作業項目がある場合、25のスレッドはあまり役に立ちません。各CPUに1つずつ、2つのスレッドを持つ方が良い

TPLとPLINQを調査する価値があるかもしれません:

使用中のTPLの例の1つは次のとおりです。

for (int i = 0; i < 100; i++) { 
  a[i] = a[i]*a[i]; 
}

to:

Parallel.For(0, 100, delegate(int i) { 
  a[i] = a[i]*a[i]; 
});
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top