2
System.Threading.ThreadPool.SetMaxThreads(50, 50);
File.ReadLines().AsParallel().WithDegreeOfParallelism(100).ForAll((s)->{
/*
some code which is waiting external API call 
and do not utilize CPU 
*/
});

システムのスレッド数が CPU 数を超えたことはありません。PLINQ を使用して、CPU ごとに複数のスレッドを取得できますか?

4

5 に答える 5

4

外部 Web API を呼び出している場合は、2 に設定されている同時同時接続の制限に達している可能性があります。アプリケーションの最初に、次の操作を行います。

System.Net.ServicePointManager.DefaultConnectionLimit = 4096;
System.Net.ServicePointManager.Expect100Continue = false;

それが役立つかどうか試してください。そうでない場合は、並列化しようとしているルーチン内に他のボトルネックがある可能性があります。

また、他のレスポンダーが言ったように、ThreadPool は負荷に基づいてスピンアップするスレッドの数を決定します。TPL での私の経験では、時間の経過とともにスレッド数が増加することがわかりました。アプリの実行時間が長くなり、負荷が重くなると、より多くのスレッドがスピンアップされます。

于 2013-10-28T15:21:47.813 に答える
1

PLINQ は山登りアルゴリズムを使用して、TPL で使用されるスレッド プールの最適なサイズを決定します。タスクに多くの I/O を配置する場合、CPU 数よりも多くのスレッドが表示されるのは好感が持てると思います。

そうは言っても、CPUカウントよりも多くのスレッドを見たことはありません:)。しかし、おそらく私は適切な状況にあったことはありません。

于 2013-10-28T15:21:38.923 に答える
1

これを次のコードでテストしました。

var lines = Enumerable.Range(0, 200).ToArray();
int currentThreads = 0;
int maxThreads = 0;
object l = new object();
lines.AsParallel().WithDegreeOfParallelism(100).ForAll(
    s =>
    {
        lock (l)
        {
            currentThreads++;
            if (currentThreads > maxThreads)
            {
                maxThreads = currentThreads;
                Console.WriteLine(maxThreads);
            }
        }
        Thread.Sleep(3000);
        lock (l)
        {
            currentThreads--;
        }
    });

Console.WriteLine();
Console.WriteLine(maxThreads);

基本的に、同時に実行されている反復の現在の数を記録し、検出された最大値を保存します。

結果は 15 から 25 の間でかなり異なりますが、常にコンピューターの CPU の数 (4) よりもはるかに多くなっています。スリープ時間を増やすと、同時スレッドの最大数が増えます。したがって、ここでの制限要因は次のように見えますThreadPool。特に、ジョブが比較的迅速に完了している場合は、新しいスレッドの作成が遅くなります。

使用するスレッド数を増やしたい場合は、SetMinThreads()(not SetMaxThreads()) を使用する必要があります。最小値を 50 に設定すると、実際に使用されるスレッドの数は約 60 になります。

しかし、待つだけのスレッドを何十個も持つことは、特にメモリ消費に関しては非常に非効率的です。代わりに非同期メソッドの使用を検討する必要があります。

于 2013-10-28T16:36:10.663 に答える
0

この場合、PLINQ は適合しません。次の記事が役に立ちました。 http://msdn.microsoft.com/en-us/library/hh228609(v=vs.110).aspx

于 2013-10-28T19:11:48.253 に答える
-1

簡単な答え: いいえ。

スレッド化の量は、単純に .Net Framework ランタイムまでです。TPL (タスク並列ライブラリ) を使用するためのスレッド数を制御するための開発者制御はありません。

編集

他のフィードバックのおかげで、PLINQ と TPL が使用する ThreadPool 内のスレッド数を手動で制御することは実際には可能ですが、推奨されません。

並列化の問題はすべて慎重に検討し、慎重に構築してテストする必要があるというのが私の意見です。これには多くの微妙な点があります。

于 2013-10-28T15:16:44.507 に答える