Diría que TPL Dataflow cubre un subconjunto especializado de funcionalidad en Rx. El flujo de datos es para el procesamiento de datos, que puede tomar una cantidad medible de tiempo, mientras que Rx es para eventos, como la posición del mouse, estados de error, etc. donde el tiempo de manipulación es insignificante.
Ejemplo: su controlador "suscribir" es asincrónico y no desea tener más de 1 ejecutor en ese momento. Con Rx tienes que bloquear, no hay otra forma de evitarlo, porque Rx es asíncrona y no amenaza asincrónica de manera especial en muchos lugares.
.Subscribe(myAsyncHandler().Result)
Si no bloquear, entonces Rx considerará que la acción es completa, mientras manejador todavía se está ejecutando de forma asíncrona.
Se podría pensar que si lo hace
.ObserveOn(Scheduler.EventLoopSchedule)
de problema está resuelto. Pero esto romperá su flujo de trabajo .Complete(), porque Rx pensará que se realizará tan pronto como programe la ejecución y saldrá de la aplicación sin esperar a que se complete la operación asincrónica.
Si no desea permitir más de 4 tareas simultáneas simultáneas, Rx no ofrece nada de fábrica. Quizás pueda piratear algo implementando su propio programador, búfer, etc.
TPL Dataflow ofrece una solución muy buena en ActionBlock.Puede limitar las acciones simultáneas a cierto número y comprende las operaciones asincrónicas, de modo que al llamar a Complete() ya la espera de Completed hará exactamente lo que cabría esperar: esperar a que se completen todas las tareas asincrónicas en progreso.
Otra característica que tiene TPL es "contrapresión". Digamos que descubrió un error en su rutina de manejo y necesita recalcular los datos del mes pasado. Si se suscribe a su fuente utilizando Rx, y su canalización contiene búferes ilimitados u ObserveOn, se le agotará la memoria en cuestión de segundos porque la fuente seguirá leyendo más rápido de lo que el procesamiento puede manejar. Incluso si implementa el bloqueo de los consumidores, su fuente puede sufrir bloqueos de llamadas, por ejemplo, si la fuente es asincrónica. En TPL puede implementar el código fuente como
while(...)
await actionBlock.SendAsync(msg)
que no bloquea la fuente aún mientras el controlador está sobrecargado.
En general, encontré que Rx es adecuado para acciones que son lentas y computacionalmente livianas. Si el tiempo de procesamiento se vuelve sustancial, se encuentra en el mundo de los extraños efectos secundarios y la depuración esotérica.
La buena noticia es que los bloques TPL Dataflow funcionan muy bien con Rx. Tienen adaptadores AsObserver/AsObservable y puede colocarlos en el medio de la tubería Rx cuando sea necesario. Pero Rx tiene muchos más patrones y casos de uso. Así que mi regla de oro es comenzar con Rx y agregar TPL Dataflow según sea necesario.
enlace a mayores, cerrado, pregunta duplicado: http://stackoverflow.com/questions/2138361/reactive-framework-vs-plinq-vs-task-parallel-library-vs-parallel-extensions/2188259 – yzorg