Delen via


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. Hoewel NotBuffered 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 dan NotBuffered 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.

Zie ook