Share via


Opciones de combinación en PLINQ

Cuando una consulta se ejecuta en paralelo, PLINQ crea particiones en la secuencia de origen para que varios subprocesos puedan funcionar simultáneamente en diferentes partes, por lo general en subprocesos independientes. Si los resultados se van a usar en un subproceso, por ejemplo, en un bucle foreach (For Each en Visual Basic), los resultados de cada subproceso deben volver a combinarse en una secuencia. El tipo de combinación que PLINQ realiza depende de los operadores que se encuentran 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 el punto de vista del subproceso utilizado (qué también es el del usuario de la aplicación), una consulta totalmente almacenada en búfer podría ejecutarse durante un período notable de tiempo antes de generar su primer resultado. Otros operadores se almacenan parcialmente en búfer de forma predeterminada; producen sus resultados en lotes. Un operador ForAll<TSource> no se almacena en búfer de forma predeterminada. Produce inmediatamente todos los elementos de todos los subprocesos.

Como se muestra en el siguiente ejemplo, con el método WithMergeOptions<TSource>, puede proporcionar a PLINQ una sugerencia que indica el tipo de combinación que se va a realizar.

        Dim scanlines = From n In nums.AsParallel().WithMergeOptions(ParallelMergeOptions.NotBuffered)
                        Where n Mod 2 = 0
                        Select ExpensiveFunc(n)

var scanLines = from n in nums.AsParallel()
                    .WithMergeOptions(ParallelMergeOptions.NotBuffered)
                where n % 2 == 0
                select ExpensiveFunc(n);

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

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

ParallelMergeOptions

La enumeración ParallelMergeOptions incluye las siguientes opciones que especifican, para las formas de la consulta compatibles, cómo se proporciona el resultado final de la consulta cuando se usan los resultados en un subproceso:

  • Not Buffered

    La opción NotBuffered hace que cada subproceso devuelva cada elemento procesado en cuanto se genere. Este comportamiento es análogo a la "transmisión por secuencias" del resultado. Si el operador AsOrdered() se encuentra en la consulta, NotBuffered conserva el orden de los elementos de origen. Aunque NotBuffered empieza a proporcionar los resultados en cuanto están disponibles, el tiempo total para generar todos los resultados podría ser aún más prolongado que al usar una de las otras opciones de combinación.

  • Auto Buffered

    La opción AutoBuffered hace que la consulta recopile los elementos en un búfer y, a continuación, proporcione periódicamente todo el contenido del búfer a la vez para el subproceso utilizado. Esto es análogo a proporcionar los datos de origen en "fragmentos" en lugar de usar el comportamiento de "transmisión por secuencias" de NotBuffered. AutoBuffered puede llevar mucho más tiempo que NotBuffered para hacer que el primer elemento esté disponible en el subproceso utilizado. El tamaño del búfer y el comportamiento productivo exacto no se puede configurar y puede 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 proporcione cualquiera de los elementos. Cuando se usa esta opción, puede llevar mucho más tiempo que el primer elemento esté disponible en el subproceso utilizado, pero los resultados completos se podrían generar aún más rápidamente que al usar las otras opciones.

Operadores de consulta que admiten opciones de combinación

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

Operador

Restricciones

AsEnumerable<TSource>

Ninguna

Cast<TResult>

Ninguna

Concat

Consultas no ordenadas que solo tienen un origen de matriz o lista.

DefaultIfEmpty

Ninguna

OfType<TResult>

Ninguna

Reverse<TSource>

Consultas no ordenadas que solo tienen un origen de matriz o lista.

Select

Ninguna

SelectMany

Ninguna

Skip<TSource>

Ninguna

Take<TSource>

Ninguna

Where

Ninguna

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<TSource> y OrderBy, no pueden proporcionar ningún elemento hasta que todos se hayan generado y reordenado. Por consiguiente, cuando se usa ParallelMergeOptions en una consulta que también contiene a operador como Reverse<TSource>, el comportamiento de combinación no se aplicará en la consulta hasta 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 operador AsOrdered se usó anteriormente en la consulta. ForAll<TSource> siempre es NotBuffered; proporciona sus elementos inmediatamente. OrderBy siempre es FullyBuffered; debe ordenar la lista completa antes de proporcionar resultados.

Vea también

Tareas

Cómo: Especificar opciones de combinación en PLINQ

Conceptos

Parallel LINQ (PLINQ)