Parallel.ForEachを制限するにはどうすればよいですか?


295

Parallel.ForEach()非同期ループを使用して、いくつかのWebページをダウンロードしています。私の帯域幅は制限されているため、一度にダウンロードできるのはxページのみですが、Parallel.ForEachは目的のWebページのリスト全体を実行します。

Parallel.ForEachの実行中にスレッド数またはその他のリミッターを制限する方法はありますか?

デモコード:

Parallel.ForEach(listOfWebpages, webpage => {
  Download(webpage);
});

実際のタスクはWebページとは何の関係もないので、独創的なWebクロールソリューションは役に立ちません。


@jKlausリストが変更されていない場合(たとえば、単なるURLのセットの場合)、問題は本当にわかりませんか?
Shiv 2016

@Shiv、十分な時間が与えられたら...実行回数を数えて、それをリストの数と比較します。
jKlaus 2016

@jKlaus何がうまくいかないの?
Shiv

1
@jKlausスレッドセーフでない要素(整数)を変更しています。そのシナリオでは機能しないと思います。一方、OPはスレッドセーフにする必要があるものを変更しません。
Shiv 2016

2
@jKlausこれは、カウントを正しく設定するParallel.ForEachの例です> dotnetfiddle.net/moqP2C。MSDNリンク:msdn.microsoft.com/en-us/library/dd997393
v

回答:


564

あなたは指定することができますMaxDegreeOfParallelismParallelOptionsのパラメータ:

Parallel.ForEach(
    listOfWebpages,
    new ParallelOptions { MaxDegreeOfParallelism = 4 },
    webpage => { Download(webpage); }
);

MSDN:Parallel.ForEach

MSDN:ParallelOptions.MaxDegreeOfParallelism


59
これはこの特定のケースには当てはまらないかもしれませんが、誰かがこれを気にして便利だと思った場合に備えて、私はそれを捨てると思いました。ここでは、プロセッサ数の75%(切り上げ)を使用しています。 var opts = new ParallelOptions { MaxDegreeOfParallelism = Convert.ToInt32(Math.Ceiling((Environment.ProcessorCount * 0.75) * 1.0)) };
jKlaus

4
ドキュメンテーションで調べなければならない人を救うために、の値を渡すこと-1は、それをまったく指定しないことと同じです:「[値]が-1の場合、同時に実行する操作の数に制限はありません」
2016

ドキュメントからはわかりません-MaxDegreeOfParallelismを4に設定すると(たとえば)ループ反復の1/4を実行するスレッドが4つある(ディスパッチされる4スレッドの1ラウンド)、または各スレッドが1つのループを実行することを意味します反復と並列実行の数を制限しているだけですか?
ハッシュマン2017年

7
コアとスレッドを明確にすることは同じことではありません。CPUに応じて、コアごとに異なるスレッド数があり、通常はコアごとに2つです。たとえば、コアあたり2スレッドの4コアCPUがある場合、最大8スレッドになります。@jKlausコメントを調整しvar opts = new ParallelOptions { MaxDegreeOfParallelism = Convert.ToInt32(Math.Ceiling((Environment.ProcessorCount * 0.75) * 2.0)) };ます。コア対スレッドへのリンク- askubuntu.com/questions/668538/...
TheMiddleMan

41

ParallelOptionsを使用してMaxDegreeOfParallelismを設定すると、同時スレッドの数を制限できます。

Parallel.ForEach(
    listOfwebpages, 
    new ParallelOptions{MaxDegreeOfParallelism=2}, 
    webpage => {Download(webpage);});     

21

別のオーバーロードを使用するParallel.ForeachことがかかりParallelOptionsインスタンス、およびセットをMaxDegreeOfParallelism並列に実行する方法を多くの場合限界。


11

そしてVB.netユーザーにとって(構文は奇妙で見つけにくい)...

Parallel.ForEach(listOfWebpages, New ParallelOptions() With {.MaxDegreeOfParallelism = 8}, Sub(webpage)
......end sub)  
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.