Compartir vía


Opciones de combinación en PLINQ

Cuando una consulta se ejecuta como paralela, PLINQ particiona la secuencia de origen para que varios subprocesos puedan trabajar en diferentes partes simultáneamente, normalmente en subprocesos independientes. Si los resultados se van a consumir en un subproceso, por ejemplo, en un foreach bucle (For Each en Visual Basic), los resultados de cada subproceso deben combinarse de nuevo en una secuencia. El tipo de combinación que realiza PLINQ depende de los operadores presentes en la consulta. Por ejemplo, los operadores que imponen un nuevo orden en los resultados deben almacenar en búfer todos los elementos de todos los subprocesos. Desde la perspectiva del subproceso de consumo (que también es el del usuario de la aplicación) una consulta totalmente almacenada en búfer podría ejecutarse durante un período de tiempo notable antes de generar su primer resultado. Otros operadores, de forma predeterminada, están parcialmente almacenados en búfer; producen sus resultados en lotes. Un operador, ForAll, no se almacena en búfer de forma predeterminada. Genera inmediatamente todos los elementos de todos los subprocesos.

Con el WithMergeOptions método , como se muestra en el ejemplo siguiente, puede proporcionar una sugerencia a PLINQ que indique qué tipo de combinación se va a realizar.

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)

Para obtener el ejemplo completo, vea Cómo: Especificar opciones de combinación en PLINQ.

Si la consulta concreta no puede admitir la opción solicitada, la opción solo se omitirá. En la mayoría de los casos, no es necesario especificar una opción de combinación para una consulta PLINQ. Sin embargo, en algunos casos puede encontrar mediante pruebas y medidas que una consulta se ejecuta mejor en un modo no predeterminado. Un uso común de esta opción es forzar un operador de combinación de fragmentos para transmitir sus resultados con el fin de proporcionar una interfaz de usuario más dinámica.

ParallelMergeOptions

La ParallelMergeOptions enumeración incluye las siguientes opciones que especifican, para las formas de consulta admitidas, cómo se produce la salida final de la consulta cuando se consumen los resultados en un subproceso:

  • Not Buffered

    La opción NotBuffered provoca que cada elemento procesado se devuelva desde cada hilo tan pronto como se produzca. Este comportamiento es análogo a la transmisión de la salida. Si el AsOrdered operador está presente en la consulta, NotBuffered conserva el orden de los elementos de origen. Aunque NotBuffered comienza a producir resultados tan pronto como estén disponibles, el tiempo total para generar todos los resultados podría ser más largo que usar una de las otras opciones de combinación.

  • Auto Buffered

    La opción AutoBuffered hace que la consulta recopile elementos en un búfer y luego entregue periódicamente todo el contenido del búfer al hilo consumidor. Esto es análogo a entregar los datos de origen en "fragmentos" en lugar de usar el comportamiento de "streaming" de NotBuffered. AutoBuffered puede tardar más que NotBuffered en habilitar el primer elemento en el subproceso utilizado. El tamaño del búfer y el comportamiento exacto de rendimiento no son configurables y pueden variar, en función de varios factores relacionados con la consulta.

  • FullyBuffered

    La opción FullyBuffered hace que el resultado de la consulta completa se almacene en búfer antes de que se produzca cualquiera de los elementos. Cuando se usa esta opción, puede tardar más tiempo antes de que el primer elemento esté disponible en el subproceso de consumo, pero es posible que los resultados completos se produzcan más rápido que mediante el uso de las otras opciones.

Operadores de consulta que admiten opciones de combinación

En la tabla siguiente se enumeran los operadores que admiten todos los modos de opción de combinación, sujetos a las restricciones especificadas.

Operador Restricciones
AsEnumerable Ninguno
Cast Ninguno
Concat Consultas no ordenadas que solo tienen un origen de matriz o lista.
DefaultIfEmpty Ninguno
OfType Ninguno
Reverse Consultas no ordenadas que solo tienen un origen de matriz o lista.
Select Ninguno
SelectMany Ninguno
Skip Ninguno
Take Ninguno
Where Ninguno

Todos los demás operadores de consulta PLINQ podrían omitir las opciones de combinación proporcionadas por el usuario. Algunos operadores de consulta, por ejemplo, Reverse y OrderBy, no pueden producir ningún elemento hasta que todos se hayan generado y reordenado. Por lo tanto, cuando ParallelMergeOptions se usa en una consulta que también contiene un operador como Reverse, el comportamiento de combinación no se aplicará en la consulta hasta después de que ese operador haya generado sus resultados.

La capacidad de algunos operadores para controlar las opciones de combinación depende del tipo de la secuencia de origen y de si el AsOrdered operador se usó anteriormente en la consulta. ForAll siempre es NotBuffered; produce inmediatamente sus elementos. OrderBy es siempre FullyBuffered; debe ordenar toda la lista antes de dar resultados.

Consulte también