Tengo una canalización secuencial que consta de dos pasos.
(ejemplo simplificado)
El primer paso simplemente suma 1000 al número de entrada. El segundo paso simplemente muestra el número.
var transformBlock = new TransformBlock<int, long>(StepOne, new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = 1, BoundedCapacity = DataflowBlockOptions.Unbounded, }); var actionBlock = new ActionBlock<long>(StepTwo, new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = 1, BoundedCapacity = 2, }); transformBlock.LinkTo(actionBlock, new DataflowLinkOptions { PropagateCompletion = true }); for (int i = 0; i < 100; i++) { transformBlock.Post(i); } static async Task<long> StepOne(int item) { await Task.Delay(500); Console.WriteLine("transforming: " + item); return (long)item + 1000; } static async Task StepTwo(long item) { await Task.Delay(1000); Console.WriteLine("final product: " + item); }Dado que el paso 2 tarda más que el paso 1, esperaría que el paso 1 se acelere después de un tiempo, ya que no puede enviar el resultado al búfer limitado del paso 2.
Rendimiento esperado:
Transformando: 0
Transformando: 1
Producto final: 1000
Transformando: 2
Producto final: 1001
Transformando: 3
Producto final: 1002
Transformando: 4
Producto final: 1003
...
Salida real:
Transformando: 0
Transformando: 1
Producto final: 1000
Transformando: 2
Transformando: 3
Producto final: 1001
Transformando: 4
Transformando: 5
Producto final: 1002
Transformando: 6
Transformando: 7
Producto final: 1003
...
Un TransformBlock mantiene dos colas internamente, una cola de entrada y una cola de salida. El tamaño de estas dos colas se puede monitorear en cualquier momento a través de las propiedades InputCount y OutputCount . El tamaño acumulado de estas dos colas está configurado por la opción BoundedCapacity , por lo que la suma InputCount + OutputCount siempre es menor o igual que el valor BoundedCapacity . En su caso, la BoundedCapacity del bloque es Unbounded , por lo que no hay un factor limitante en el tamaño de estas dos colas (aparte de algunos límites estrictos como Int32.MaxValue probablemente). El hecho de que el ActionBlock vinculado tenga una capacidad limitada limitada es en su mayoría irrelevante y no tiene otra consecuencia que retrasar la transferencia de los valores transformados desde la cola de salida del TransformBlock a la cola de entrada del ActionBlock . Esta consecuencia solo es observable si supervisa la propiedad OutputCount del bloque de origen y la propiedad InputCount del bloque de destino. Ni siquiera importaría si el TransformBlock no estuviera vinculado a ningún bloque de destino. Continuaría felizmente procesando números por sí mismo, hasta que se alcanzara algún límite estricto o se agotara la memoria de la máquina.