Sdílet prostřednictvím


Možnosti sloučení v PLINQ

Když se dotaz spouští paralelně, PLINQ rozdělí zdrojovou sekvenci tak, aby více vláken fungovalo na různých částech souběžně, obvykle na samostatných vláknech. Pokud se mají výsledky spotřebovávat na jednom vlákně, například ve foreach smyčce (For Each v jazyce Visual Basic), musí být výsledky z každého vlákna sloučeny zpět do jedné sekvence. Druh sloučení, který PLINQ provádí, závisí na operátorech, které jsou přítomné v dotazu. Například operátory, které pro výsledky ukládají nové pořadí, musí ukládat všechny prvky do vyrovnávací paměti ze všech vláken. Z pohledu náročného vlákna (což je také uživatel aplikace) může plně uložená vyrovnávací paměť dotazu běžet po znatelnou dobu, než vytvoří první výsledek. Ostatní operátory jsou ve výchozím nastavení částečně vyrovnávací paměti; jejich výsledky v dávkách. Jeden operátor není ForAll ve výchozím nastavení uložen do vyrovnávací paměti. Poskytuje všechny prvky ze všech vláken okamžitě.

WithMergeOptions Pomocí metody, jak je znázorněno v následujícím příkladu, můžete poskytnout nápovědu pro PLINQ, která označuje, jaký druh slučování provést.

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)

Úplný příklad naleznete v tématu Postupy: Určení možností sloučení v PLINQ.

Pokud konkrétní dotaz požadovanou možnost nepodporuje, bude tato možnost ignorována. Ve většině případů není nutné zadat možnost sloučení pro dotaz PLINQ. Vněkterýchchcíchchch zařízeních však Běžným použitím této možnosti je vynucení operátoru slučování bloků dat streamovat výsledky za účelem zajištění responzivního uživatelského rozhraní.

ParallelMergeOptions

Výčet ParallelMergeOptions obsahuje následující možnosti, které určují podporované obrazce dotazu, jak se konečný výstup dotazu získá, když se výsledky spotřebují na jednom vlákně:

  • Not Buffered

    Tato NotBuffered možnost způsobí, že se každý zpracovaný prvek vrátí z každého vlákna, jakmile se vytvoří. Toto chování je podobné "streamování" výstupu. AsOrdered Pokud je operátor v dotazu, NotBuffered zachová pořadí zdrojových prvků. I když NotBuffered se začnou zobrazovat výsledky hned, jak budou dostupné, může být celková doba, po kterou se všechny výsledky vytvoří, delší, než když použijete některou z ostatních možností sloučení.

  • Auto Buffered

    Tato AutoBuffered možnost způsobí, že dotaz shromáždí prvky do vyrovnávací paměti a pak pravidelně vyvolá obsah vyrovnávací paměti najednou do spotřebovávající vlákno. To je analogické k tomu, aby se zdrojová data v "blocích" místo použití "streamování" chování NotBuffered. AutoBuffered může trvat déle, než NotBuffered aby byl první prvek dostupný na spotřebovávajícím vlákně. Velikost vyrovnávací paměti a přesné chování při výnosu nelze konfigurovat a může se lišit v závislosti na různých faktorech, které se vztahují k dotazu.

  • FullyBuffered

    Tato FullyBuffered možnost způsobí, že se výstup celého dotazu uloží do vyrovnávací paměti před tím, než se vrátí některý z prvků. Pokud použijete tuto možnost, může trvat déle, než bude první prvek dostupný ve vlákně s využitím, ale úplné výsledky se můžou vytvořit rychleji než pomocí ostatních možností.

Operátory dotazů, které podporují možnosti sloučení

Následující tabulka uvádí operátory, které podporují všechny režimy možností sloučení, s výhradou zadaných omezení.

Operátor Omezení
AsEnumerable Nic
Cast Nic
Concat Neřazené dotazy, které mají pouze zdroj pole nebo seznamu.
DefaultIfEmpty Nic
OfType Nic
Reverse Neřazené dotazy, které mají pouze zdroj pole nebo seznamu.
Select Nic
SelectMany Žádné
Skip Žádné
Take Žádné
Where Nic

Všechny ostatní operátory dotazu PLINQ můžou ignorovat možnosti sloučení poskytnuté uživatelem. Některé operátory dotazů, například a OrderBy, nemohou přinést žádné prvky, Reverse dokud nebyly vytvořeny a znovu seřazeny. Proto pokud ParallelMergeOptions se použije v dotazu, který obsahuje také operátor, například Reverse, slučovací chování se v dotazu nepoužije, dokud tento operátor nevygeneruje výsledky.

Schopnost některých operátorů zpracovávat možnosti sloučení závisí na typu zdrojové sekvence a na tom, jestli AsOrdered byl operátor použit dříve v dotazu. ForAll je vždy NotBuffered ; dává své prvky okamžitě. OrderBy je vždy FullyBuffered; musí seřadit celý seznam před jeho výnosem.

Viz také