multithreading - example - c# as parallel
F#: Asynch y tareas y PLINQ, ¡oh Dios mío! (2)
Los flujos de trabajo asincrónicos se implementan a través de la sintaxis monódica F #. Esto significa que en lugar de transformar sus flujos de trabajo en tareas, podría escribir su propia versión de "asincronización" basada en la biblioteca de tareas paralelas. Lo digo con un par de advertencias:
- Sería difícil de hacer
- Las opertaciones asincrónicas que usan el patrón BeginXxx / EndXxx en .NET registran devoluciones de llamadas en el grupo de subprocesos. No estoy seguro de que pueda cambiar esto, para redirigirlos a usar tareas en su lugar.
Para obtener más detalles sobre cómo implementar una mónada en F #, consulte el libro "Expert F #" o google un poco en "Mónadas F #".
No es una respuesta completa, lo sé, pero espero que ayude un poco.
Cuando salga F #, voy a tener una vergüenza de riquezas en el área de programación asincrónica / paralela. Una respuesta a esta pregunta es un buen trabajo al describir las diferencias entre Tareas, Parallel LINQ y Reactive Framework, pero me preguntaba cómo encajan exactamente los flujos de trabajo asincrónicos en la imagen.
Corrígeme si me equivoco, pero como entiendo, los flujos de trabajo de asincronización serán la forma más fácil de trabajar con operaciones vinculadas a IO, particularmente aquellas que tienen un método AsynchXxx definido, o siguen el patrón BeginXxx / EndXxx. Otra ventaja es que los flujos de trabajo de asincronización son compostables y pueden construirse a partir de otros flujos de trabajo de asincronización, lo que permite una gran flexibilidad en la estructura de un programa.
Creo que lo que necesito ayuda es entender en qué circunstancias elegiría tareas o PLINQ sobre flujos de trabajo asíncronos, en código F #. Creo que he leído que la Biblioteca de tareas paralelas tiene formas más sofisticadas de equilibrar la carga entre los núcleos. Si eso es cierto, entonces las Tareas podrían ser una mejor opción para las operaciones puramente vinculadas a la CPU que necesitan operar en paralelo. PLINQ, por otro lado, parece ser principalmente una forma conveniente de paralelizar código existente que funciona con secuencias.
Finalmente, asumiendo que mi comprensión de las fortalezas de cada enfoque es correcta, ¿es posible o recomendable combinarlas? Por ejemplo, quizás uno podría componer una serie de operaciones a partir de flujos de trabajo asíncronos y luego transformarlas en Tareas antes de la ejecución. Si eso es posible, o incluso una buena idea.
Ver Tarea paralela Biblioteca vs Async Workflows .
Resumiría los conceptos básicos de la siguiente manera:
Biblioteca paralela de tareas : permite que múltiples unidades de trabajo se ejecuten de manera eficiente en múltiples núcleos, incluidos escenarios relativamente simples como engendrar múltiples hilos para realizar cálculos similares en paralelo, así como operaciones más complicadas donde los cálculos mismos también terminan generando tareas adicionales. Utiliza el hilo de rosca de .NET 4.0 mejorado y las colas de robo de trabajo para garantizar que todos los núcleos se mantengan ocupados.
Flujos de trabajo asincrónicos: permite que los cálculos asincrónicos se ejecuten sin ocupar hilos innecesarios, iniciando devoluciones de llamada cuando los resultados están disponibles.
PLINQ : El código escrito usando PLINQ termina ejecutándose a través del TPL, pero esta es una interfaz más agradable para el código que se expresa fácilmente usando consultas LINQ (por ejemplo, haciendo una sola operación en cada elemento en una matriz de datos en paralelo).
Tenga en cuenta que los flujos de trabajo asincrónicos se pueden convertir a Tareas con el método StartAsTask
, y que las Tareas se pueden convertir en Async
mediante el método Async.AwaitTask
, por lo que es posible Async.AwaitTask
las tecnologías, aunque apuntan a escenarios de objetivos ligeramente diferentes.
Para mí, la regla de oro sería que si estás haciendo muchos cálculos de manera activa en diferentes hilos, querrás usar el TPL (posiblemente a través de PLINQ o un equivalente de F # como el módulo PSeq), mientras que si " Al tratar de hacer un montón de IO (ya sea en paralelo o no), debe usar flujos de trabajo de asincronización. Por lo tanto, un rastreador de rayos usaría TPL para iniciar tareas para renderizar cada píxel (o línea de exploración) en paralelo, lo que maximizaría la potencia informática disponible en su computadora. Pero la descarga de un montón de páginas web se haría con flujos de trabajo asíncronos, ya que no hay mucho cálculo para distribuir entre núcleos; solo necesita ser notificado por el SO cuando los resultados han llegado.