f# asynchronous task-parallel-library

f# - Task Parallel Library vs Async Workflows



asynchronous task-parallel-library (2)

El nombre prácticamente resume la diferencia: programación asíncrona vs. programación en paralelo . Pero en F # puedes mezclar y combinar.

F # Flujos de trabajo asincrónicos

Los flujos de trabajo asincrónicos de F # son útiles cuando se desea que el código se ejecute de forma asíncrona, es decir, se inicia una tarea y no se espera el resultado final. El uso más común de esto es operaciones IO. Tener el hilo sentado allí en un bucle inactivo esperando a que su disco duro termine de escribir desperdicia recursos.

Si comenzó la operación de escritura de forma asíncrona, puede suspender el hilo y hacer que lo despierte más tarde una interrupción de hardware.

Tarea Biblioteca paralela

La Biblioteca de tareas paralelas en .NET 4.0 abstrae la noción de una tarea, como decodificar un MP3 o leer algunos resultados de una base de datos. En estas situaciones, realmente desea el resultado del cálculo y en algún momento posterior está esperando el resultado de la operación. (Al acceder a la propiedad .Result).

Puede mezclar y combinar fácilmente estos conceptos. Como hacer todas sus operaciones de IO en un objeto de tarea TPL. Para el programador, ha abstraído la necesidad de ''tratar'' ese hilo adicional, pero bajo las cubiertas está desperdiciando recursos.

Del mismo modo, puede crear una serie de flujos de trabajo asincrónicos F # y ejecutarlos en paralelo (Async.Parallel) pero luego debe esperar el resultado final (Async.RunSynchronously). Esto te libera de la necesidad de iniciar explícitamente todas las tareas, pero realmente solo estás realizando el cálculo en paralelo.

En mi experiencia, me parece que el TPL es más útil porque generalmente quiero ejecutar N operaciones en paralelo. Sin embargo, los flujos de trabajo asincrónicos de F # son ideales cuando hay algo que está sucediendo "detrás de escena", como un agente reactivo o una especie de tipo de buzón. (Envía algo a un mensaje, lo procesa y lo envía de vuelta).

Espero que ayude.

Tengo algunas cosas escritas en c # que ejecuta código concurrente, haciendo un uso intensivo de la Biblioteca paralela de tareas (cadenas de continuación de tareas y futuras).

Ahora estoy transfiriendo esto a F # y estoy tratando de descubrir los pros y los contras del uso de flujos de trabajo F # Async frente a los constructos en el TPL. Me inclino por TPL, pero creo que podría hacerse de cualquier manera.

¿Alguien tiene consejos y sabiduría para escribir programas concurrentes en F # para compartir?


En 4.0 diría:

  • Si su función es secuencial, use flujos de trabajo Async. Simplemente leen mejor.
  • Usa el TPL para todo lo demás.

También es posible mezclar y combinar. Han agregado soporte para ejecutar un flujo de trabajo como una tarea y crear tareas que siguen el patrón asincrónico Begin / End usando TaskFactory.FromAsync , el equivalente TPL de Async.FromBeginEnd o Async.BuildPrimitive .

let func() = let file = File.OpenRead("foo") let buffer = Array.zeroCreate 1024 let task1 = Task.Factory.FromAsync(file.BeginRead(buffer, 0, buffer.Length, null, null), file.EndRead) task1.Start() let task2 = Async.StartAsTask(file.AsyncRead(1024)) printfn "%d" task2.Result.Length

También vale la pena señalar que tanto el tiempo de ejecución de Async Workflows como el TPL van a crear una primitiva de núcleo adicional (un Evento) y usar WaitForMultipleObjects para rastrear la finalización de E / S, en lugar de usar puertos de terminación y devoluciones de llamada. Esto es indeseable en algunas aplicaciones.