23

次の 2 つのアプローチの主な違いは何ですか。

ThreadPool.QueueUserWorkItem

    Clients objClient = new Clients();
    List<Clients> objClientList = Clients.GetClientList();

    foreach (var list in objClientList)
    {
        ThreadPool.QueueUserWorkItem(new WaitCallback(SendFilesToClient), list);
    } 

System.Threading.Tasks.Parallel ForEach

    Clients objClient = new Clients();
    List<Clients> objClientList = Clients.GetClientList();

    Parallel.ForEach<Clients>(objClientList, list =>
    {
        SendFilesToClient(list);
    });

私はマルチスレッドが初めてで、各ケースで何が起こるかを知りたいです (実行プロセスに関して) 各アプローチのマルチスレッドのレベルは何ですか? 両方のプロセスを視覚化するのを手伝ってください。

SendFilesToClient:データベースからデータを取得し、Excel に変換して、Excel ファイルをそれぞれのクライアントに送信します。

ありがとう!

4

1 に答える 1

24

主な違いは機能です。 Parallel.ForEachは (設計により) ブロックするため、すべてのオブジェクトが処理されるまで返されません。foreachキューイング スレッドプール スレッド作業は、作業をバックグラウンド スレッドにプッシュし、ブロックしません。

また、このParallel.ForEachバージョンには別の大きな利点があります。未処理の例外は、ThreadPool スレッドで未処理のままになるのではなく、ここで呼び出しサイトにプッシュバックされます。

一般的に、Parallel.ForEachより効率的になります。どちらのオプションも ThreadPool を使用しますが、Parallel.ForEachインテリジェントなパーティショニングを行ってオーバースレッドを防ぎ、スケジューラが必要とするオーバーヘッドの量を減らします。SendFilesToClient個々のタスク (ThreadPool スレッドにマップされる) は再利用され、特に高速な操作の場合 (この場合は当てはまらない)、オーバーヘッドを下げるために効果的に「プール」されます。

3 番目のオプションとして、PLINQ を使用することもできます。

objClientList.AsParallel().ForAll(SendFilesToClient);

Parallel.ForEachこれは、パフォーマンスと機能の点でメソッドに非常に似ています。

于 2013-02-27T21:30:29.507 に答える