Remarque
L’accès à cette page requiert une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page requiert une autorisation. Vous pouvez essayer de modifier des répertoires.
Lorsqu’une requête s’exécute en parallèle, PLINQ partitionne la séquence source afin que plusieurs threads puissent fonctionner simultanément sur différentes parties, généralement sur des threads distincts. Si les résultats doivent être consommés sur un thread, par exemple, dans une foreach boucle (For Each en Visual Basic), les résultats de chaque thread doivent être fusionnés dans une seule séquence. Le type de fusion que PLINQ effectue dépend des opérateurs présents dans la requête. Par exemple, les opérateurs qui imposent un nouvel ordre aux résultats doivent mettre en mémoire tampon tous les éléments de tous les threads. Du point de vue du thread consommant (qui est également celui de l’utilisateur de l’application), une requête entièrement mise en mémoire tampon peut s’exécuter pendant une période notable avant de produire son premier résultat. D’autres opérateurs, par défaut, sont partiellement mis en mémoire tampon ; ils produisent leurs résultats par lots. Un opérateur ForAll n’est pas mis en mémoire tampon par défaut. Elle génère tous les éléments de tous les threads immédiatement.
À l’aide de la WithMergeOptions méthode, comme illustré dans l’exemple suivant, vous pouvez fournir un indicateur à PLINQ qui indique le type de fusion à effectuer.
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)
Pour obtenir l’exemple complet, consultez Comment : spécifier des options de fusion dans PLINQ.
Si la requête particulière ne peut pas prendre en charge l’option demandée, l’option est simplement ignorée. Dans la plupart des cas, vous n’avez pas à spécifier d’option de fusion pour une requête PLINQ. Toutefois, dans certains cas, vous pouvez trouver en testant et en mesure qu’une requête s’exécute le mieux en mode non par défaut. Une utilisation courante de cette option consiste à forcer un opérateur de fusion de blocs à diffuser en continu ses résultats afin de fournir une interface utilisateur plus réactive.
Options de fusion parallèle
L’énumération ParallelMergeOptions inclut les options suivantes qui spécifient, pour les formes de requête prises en charge, la façon dont la sortie finale de la requête est générée lorsque les résultats sont consommés sur un thread :
Not BufferedL’option NotBuffered entraîne le retour de chaque élément traité à partir de chaque thread dès qu’il est généré. Ce comportement est analogue à « streaming » de la sortie. Si l’opérateur AsOrdered est présent dans la requête,
NotBufferedconserve l’ordre des éléments sources. Bien queNotBufferedcommence à produire des résultats dès qu'ils sont disponibles, le temps total pour obtenir tous les résultats pourrait être plus long que si l'on utilisait une des autres options de fusion.Auto BufferedL’option AutoBuffered entraîne la collecte des éléments dans une mémoire tampon, puis fournit périodiquement le contenu de la mémoire tampon en bloc au thread consommateur. Cela est analogue à la fourniture des données sources en « blocs » au lieu d’utiliser le mode « streaming » de
NotBuffered.AutoBufferedpeut prendre plus de temps queNotBufferedpour rendre le premier élément disponible sur le thread consommateur. La taille de la mémoire tampon et le comportement de rendement exact ne sont pas configurables et peuvent varier en fonction de différents facteurs liés à la requête.FullyBufferedL’option FullyBuffered entraîne la mise en mémoire tampon de la sortie de l’ensemble de la requête avant que l’un des éléments ne soit généré. Lorsque vous utilisez cette option, il peut prendre plus de temps avant que le premier élément soit disponible sur le thread consommateur, mais les résultats complets peuvent toujours être générés plus rapidement qu’à l’aide des autres options.
Opérateurs de requête qui prennent en charge les options de fusion
Le tableau suivant répertorie les opérateurs qui prennent en charge tous les modes d’option de fusion, soumis aux restrictions spécifiées.
| Opérateur | Restrictions |
|---|---|
| AsEnumerable | Aucun |
| Cast | Aucun |
| Concat | Requêtes non ordonnées qui ont une source de tableau ou de liste uniquement. |
| DefaultIfEmpty | Aucun |
| OfType | Aucun |
| Reverse | Requêtes non ordonnées qui ont une source de tableau ou de liste uniquement. |
| Select | Aucun |
| SelectMany | Aucun |
| Skip | Aucun |
| Take | Aucun |
| Where | Aucun |
Tous les autres opérateurs de requête PLINQ peuvent ignorer les options de fusion fournies par l’utilisateur. Certains opérateurs de requête, par exemple Reverse et OrderBy, ne peuvent pas générer d’éléments tant que tous les éléments n’ont pas été produits et réorganisés. Par conséquent, lorsqu’elle ParallelMergeOptions est utilisée dans une requête qui contient également un opérateur tel que Reverse, le comportement de fusion ne sera pas appliqué dans la requête tant qu’une fois que cet opérateur a produit ses résultats.
La capacité de certains opérateurs à gérer les options de fusion dépend du type de la séquence source et de l’utilisation de l’opérateur AsOrdered précédemment dans la requête. ForAll est toujours NotBuffered ; il produit ses éléments immédiatement. OrderBy est toujours FullyBuffered ; il doit trier l’intégralité de la liste avant toute transmission.