Opties voor samenvoegen in PLINQ
Wanneer een query als parallel wordt uitgevoerd, partitioneert PLINQ de bronreeks, zodat meerdere threads gelijktijdig op verschillende onderdelen kunnen werken, meestal op afzonderlijke threads. Als de resultaten moeten worden gebruikt voor één thread, bijvoorbeeld in een foreach
(For Each
in Visual Basic)-lus, moeten de resultaten van elke thread weer worden samengevoegd in één reeks. Het type samenvoeging dat door PLINQ wordt uitgevoerd, is afhankelijk van de operators die aanwezig zijn in de query. Operators die bijvoorbeeld een nieuwe volgorde voor de resultaten opleggen, moeten alle elementen van alle threads bufferen. Vanuit het perspectief van de verbruikende thread (die ook van de toepassingsgebruiker is) kan een volledig gebufferde query gedurende een merkbare periode worden uitgevoerd voordat het eerste resultaat wordt geproduceerd. Andere operators worden standaard gedeeltelijk gebufferd; ze leveren hun resultaten op in batches. Eén operator, ForAll wordt niet standaard gebufferd. Het levert alle elementen van alle threads onmiddellijk op.
Met behulp van de WithMergeOptions methode, zoals wordt weergegeven in het volgende voorbeeld, kunt u een hint opgeven voor PLINQ die aangeeft welk soort samenvoeging moet worden uitgevoerd.
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)
Zie Procedure voor het volledige voorbeeld : Samenvoegopties opgeven in PLINQ.
Als de betreffende query de aangevraagde optie niet kan ondersteunen, wordt de optie gewoon genegeerd. In de meeste gevallen hoeft u geen samenvoegoptie voor een PLINQ-query op te geven. In sommige gevallen kunt u echter vinden door te testen en meten dat een query het beste wordt uitgevoerd in een niet-standaardmodus. Een veelvoorkomend gebruik van deze optie is het afdwingen van een operator voor het samenvoegen van segmenten om de resultaten te streamen om een responsievere gebruikersinterface te bieden.
ParallelMergeOptions
De ParallelMergeOptions opsomming bevat de volgende opties die opgeven, voor ondersteunde queryshapes, hoe de uiteindelijke uitvoer van de query wordt gegenereerd wanneer de resultaten worden gebruikt op één thread:
Not Buffered
De NotBuffered optie zorgt ervoor dat elk verwerkt element wordt geretourneerd van elke thread zodra het wordt geproduceerd. Dit gedrag is vergelijkbaar met het 'streamen' van de uitvoer. Als de AsOrdered operator aanwezig is in de query,
NotBuffered
behoudt u de volgorde van de bronelementen. HoewelNotBuffered
er resultaten worden geretourneerd zodra ze beschikbaar zijn, kan de totale tijd voor het produceren van alle resultaten langer zijn dan het gebruik van een van de andere samenvoegopties.Auto Buffered
De AutoBuffered optie zorgt ervoor dat de query elementen in een buffer verzamelt en vervolgens periodiek de inhoud van de buffer in één keer opgeeft aan de verbruikende thread. Dit is vergelijkbaar met het opleveren van de brongegevens in 'segmenten' in plaats van het 'streaming'-gedrag van
NotBuffered
.AutoBuffered
het kan langer duren danNotBuffered
het eerste element beschikbaar maakt voor de verbruikende thread. De grootte van de buffer en het exacte rendementsgedrag kunnen niet worden geconfigureerd en kunnen variëren, afhankelijk van verschillende factoren die betrekking hebben op de query.FullyBuffered
De FullyBuffered optie zorgt ervoor dat de uitvoer van de hele query wordt gebufferd voordat een van de elementen wordt geretourneerd. Wanneer u deze optie gebruikt, kan het langer duren voordat het eerste element beschikbaar is voor de verbruikende thread, maar de volledige resultaten kunnen nog steeds sneller worden geproduceerd dan met behulp van de andere opties.
Queryoperators die ondersteuning bieden voor samenvoegopties
De volgende tabel bevat de operators die ondersteuning bieden voor alle samenvoegingsoptiemodi, afhankelijk van de opgegeven beperkingen.
Operator | Beperkingen |
---|---|
AsEnumerable | Geen |
Cast | Geen |
Concat | Niet-geordende query's met alleen een matrix- of lijstbron. |
DefaultIfEmpty | Geen |
OfType | Geen |
Reverse | Niet-geordende query's met alleen een matrix- of lijstbron. |
Select | Geen |
SelectMany | None |
Skip | None |
Take | None |
Where | Geen |
Alle andere PLINQ-queryoperators kunnen door de gebruiker geleverde samenvoegopties negeren. Sommige queryoperators kunnen bijvoorbeeld ReverseOrderBygeen elementen opleveren totdat ze allemaal zijn geproduceerd en opnieuw zijn gerangschikt. ParallelMergeOptions Wanneer wordt gebruikt in een query die ook een operator bevat, Reversewordt het samenvoeggedrag pas toegepast in de query nadat die operator de resultaten heeft geproduceerd.
De mogelijkheid van sommige operators voor het afhandelen van samenvoegopties is afhankelijk van het type bronreeks en of de AsOrdered operator eerder in de query is gebruikt. ForAll is altijd NotBuffered ; het levert zijn elementen onmiddellijk op. OrderBy is altijd FullyBuffered; het moet de hele lijst sorteren voordat deze oplevert.