6

バッチインポートで約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;
    }
 }
4

2 に答える 2

7

質問に対する文字通りの答えは、どちらもスレッドプールを使用するということです。そのため、パフォーマンスだけを考慮する場合、違いはそれほど大きくありません。

問題が本当に最高のパフォーマンスを得ることである場合は、スレッドプールの使用に問題があることを知っておくと役立つ場合があります。これらには以下が含まれます:

  • ワーク キューでのロック競合
  • 過度のコンテキスト切り替え。2 つの CPU と一連の作業項目がある場合、25 スレッドは実際には役に立ちません。各 CPU に 1 つずつ、合計 2 つのスレッドを使用することをお勧めします。

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

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

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

に:

Parallel.For(0, 100, delegate(int i) { 
  a[i] = a[i]*a[i]; 
});
于 2008-10-11T21:08:29.203 に答える
6

この場合、どちらも内部でスレッドプールを使用するため、それほど多くはありません。QueueUserWorkItem()は、BeginInvokeと比較して、何が起こっているのかを読み、確認する方が簡単だと思います。

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

于 2008-10-10T18:36:29.323 に答える