クエリが並列として実行されている場合、PLINQ はソース シーケンスをパーティション分割して、複数のスレッドが異なる部分 (通常は個別のスレッド) で同時に動作できるようにします。
foreach
(Visual Basic ではFor Each
) ループなど、1 つのスレッドで結果を使用する場合は、すべてのスレッドの結果を 1 つのシーケンスにマージする必要があります。 PLINQ が実行するマージの種類は、クエリに存在する演算子によって異なります。 たとえば、結果に新しい順序を設定する演算子は、すべてのスレッドのすべての要素をバッファーする必要があります。 消費スレッド (アプリケーション ユーザーの場合も同じ) の観点からは、完全にバッファーされたクエリは、最初の結果を生成する前に、顕著な期間実行される可能性があります。 既定では、他の演算子は部分的にバッファリングされます。結果がバッチで生成されます。 1 つの演算子 ForAll は、既定ではバッファーに格納されません。 すべてのスレッドからすべての要素がすぐに生成されます。
次の例に示すように、 WithMergeOptions メソッドを使用すると、実行するマージの種類を示すヒントを PLINQ に提供できます。
var scanLines = from n in nums.AsParallel()
.WithMergeOptions(ParallelMergeOptions.NotBuffered)
where n % 2 == 0
select ExpensiveFunc(n);
Dim scanlines = From n In nums.AsParallel().WithMergeOptions(ParallelMergeOptions.NotBuffered)
Where n Mod 2 = 0
Select ExpensiveFunc(n)
完全な例については、「 方法: PLINQ でマージ オプションを指定する」を参照してください。
特定のクエリが要求されたオプションをサポートできない場合、オプションは無視されます。 ほとんどの場合、PLINQ クエリのマージ オプションを指定する必要はありません。 ただし、場合によっては、クエリが既定以外のモードで最適に実行されることをテストおよび測定することで見つかる場合があります。 このオプションの一般的な用途は、より応答性の高いユーザー インターフェイスを提供するために、チャンクマージ演算子に結果のストリーミングを強制することです。
ParallelMergeOptions
ParallelMergeOptions列挙には、サポートされているクエリ図形に対して、結果が 1 つのスレッドで使用されたときにクエリの最終的な出力がどのように生成されるかを指定する次のオプションが含まれています。
Not Buffered
NotBuffered オプションを指定すると、処理された各要素は、生成されるとすぐに各スレッドから返されます。 この動作は、出力の "ストリーミング" に似ています。 クエリに AsOrdered 演算子が存在する場合、
NotBuffered
はソース要素の順序を保持します。NotBuffered
、使用可能になるとすぐに結果の生成が開始されますが、すべての結果を生成する合計時間が、他のマージ オプションのいずれかを使用するよりも長くなる可能性があります。Auto Buffered
AutoBuffered オプションを指定すると、クエリによって要素がバッファーに収集され、バッファーの内容がすべて消費スレッドに定期的に一度に生成されます。 これは、
NotBuffered
の "ストリーミング" 動作を使用するのではなく、ソース データを "チャンク" で生成することに似ています。AutoBuffered
は、使用しているスレッドで最初の要素を使用できるようにするには、NotBuffered
よりも長い時間がかかる場合があります。 バッファーのサイズと正確な生成動作は構成できません。また、クエリに関連するさまざまな要因によって異なる場合があります。FullyBuffered
FullyBuffered オプションを指定すると、いずれかの要素が生成される前に、クエリ全体の出力がバッファーに格納されます。 このオプションを使用する場合、最初の要素が使用しているスレッドで使用できるようになるまでに時間がかかる場合がありますが、他のオプションを使用するよりも完全な結果が高速に生成される可能性があります。
マージ オプションをサポートするクエリ演算子
次の表に、指定した制限に従って、すべてのマージ オプション モードをサポートする演算子を示します。
オペレーター | 制約 |
---|---|
AsEnumerable | 無し |
Cast | 無し |
Concat | 配列またはリスト ソースのみを持つ順序付けされていないクエリ。 |
DefaultIfEmpty | 無し |
OfType | 無し |
Reverse | 配列またはリスト ソースのみを持つ順序付けされていないクエリ。 |
Select | 無し |
SelectMany | 無し |
Skip | 無し |
Take | 無し |
Where | 無し |
他のすべての PLINQ クエリ演算子は、ユーザーが指定したマージ オプションを無視する場合があります。 ReverseやOrderByなどの一部のクエリ演算子では、すべてが生成および並べ替えされるまで要素を生成できません。 そのため、Reverseなどの演算子も含むクエリでParallelMergeOptionsを使用する場合、その演算子が結果を生成するまで、マージ動作はクエリに適用されません。
マージ オプションを処理する演算子の一部の機能は、ソース シーケンスの種類と、 AsOrdered 演算子がクエリで前に使用されたかどうかによって異なります。 ForAll は常に NotBuffered 。要素はすぐに生成されます。 OrderBy は常に FullyBuffered。生成する前にリスト全体を並べ替える必要があります。
こちらも参照ください
.NET