La Biblioteca de Tareas Paralelas (TPL) es una parte fundamental de la programación asíncrona y paralela en .NET, y F# proporciona una integración fluida con esta biblioteca. La TPL permite a los desarrolladores escribir código concurrente y paralelo de manera más sencilla y eficiente, aprovechando al máximo los recursos del sistema.
Conceptos Clave
- Tareas (Tasks)
Las tareas representan unidades de trabajo que se pueden ejecutar de manera asíncrona. En F#, las tareas se crean y gestionan utilizando el módulo System.Threading.Tasks
.
- Paralelismo
El paralelismo implica ejecutar múltiples tareas simultáneamente para mejorar el rendimiento y la eficiencia. La TPL facilita la creación y gestión de tareas paralelas.
- Continuaciones
Las continuaciones permiten especificar acciones que deben ejecutarse después de que una tarea se complete. Esto es útil para encadenar operaciones asíncronas.
Ejemplo Práctico
Crear y Ejecutar Tareas
A continuación, se muestra un ejemplo básico de cómo crear y ejecutar tareas en F# utilizando la TPL:
open System.Threading.Tasks let task1 = Task.Run(fun () -> printfn "Task 1 is running" System.Threading.Thread.Sleep(1000) printfn "Task 1 is completed" ) let task2 = Task.Run(fun () -> printfn "Task 2 is running" System.Threading.Thread.Sleep(500) printfn "Task 2 is completed" ) Task.WaitAll([| task1; task2 |]) printfn "All tasks are completed"
Explicación:
Task.Run
se utiliza para crear y ejecutar una tarea.Task.WaitAll
espera a que todas las tareas especificadas se completen antes de continuar.
Continuaciones
Las continuaciones permiten ejecutar código adicional después de que una tarea se complete:
let task = Task.Run(fun () -> printfn "Main task is running" System.Threading.Thread.Sleep(1000) 42 ) let continuation = task.ContinueWith(fun t -> printfn "Continuation task is running" printfn "Result from main task: %d" t.Result ) Task.WaitAll([| task; continuation |]) printfn "All tasks including continuation are completed"
Explicación:
ContinueWith
se utiliza para definir una tarea de continuación que se ejecuta después de que la tarea principal se complete.t.Result
obtiene el resultado de la tarea principal.
Ejercicios Prácticos
Ejercicio 1: Crear y Ejecutar Múltiples Tareas
Instrucciones:
- Crea tres tareas que impriman mensajes diferentes y duerman por diferentes duraciones.
- Utiliza
Task.WaitAll
para esperar a que todas las tareas se completen.
Solución:
open System.Threading.Tasks let task1 = Task.Run(fun () -> printfn "Task 1 is running" System.Threading.Thread.Sleep(1000) printfn "Task 1 is completed" ) let task2 = Task.Run(fun () -> printfn "Task 2 is running" System.Threading.Thread.Sleep(500) printfn "Task 2 is completed" ) let task3 = Task.Run(fun () -> printfn "Task 3 is running" System.Threading.Thread.Sleep(1500) printfn "Task 3 is completed" ) Task.WaitAll([| task1; task2; task3 |]) printfn "All tasks are completed"
Ejercicio 2: Utilizar Continuaciones
Instrucciones:
- Crea una tarea que calcule la suma de dos números.
- Define una continuación que imprima el resultado de la suma.
Solución:
let sumTask = Task.Run(fun () -> let a = 10 let b = 20 a + b ) let continuation = sumTask.ContinueWith(fun t -> printfn "The sum is: %d" t.Result ) Task.WaitAll([| sumTask; continuation |]) printfn "Sum task and continuation are completed"
Resumen
En esta sección, hemos explorado la Biblioteca de Tareas Paralelas (TPL) en F#. Hemos aprendido a crear y ejecutar tareas, así como a utilizar continuaciones para encadenar operaciones asíncronas. La TPL es una herramienta poderosa para escribir código concurrente y paralelo, y su integración con F# facilita la creación de aplicaciones eficientes y escalables.
En el próximo tema, exploraremos el uso de MailboxProcessor
y agentes para gestionar la concurrencia de manera más estructurada y segura.
Curso de Programación en F#
Módulo 1: Introducción a F#
Módulo 2: Conceptos Básicos
- Tipos de Datos y Variables
- Funciones e Inmutabilidad
- Coincidencia de Patrones
- Colecciones: Listas, Arreglos y Secuencias
Módulo 3: Programación Funcional
- Funciones de Orden Superior
- Recursión
- Encadenamiento y Composición
- Aplicación Parcial y Currificación
Módulo 4: Estructuras de Datos Avanzadas
Módulo 5: Programación Orientada a Objetos en F#
- Clases y Objetos
- Herencia e Interfaces
- Mezclando Programación Funcional y Orientada a Objetos
- Módulos y Espacios de Nombres
Módulo 6: Programación Asíncrona y Paralela
- Flujos de Trabajo Asíncronos
- Biblioteca de Tareas Paralelas
- MailboxProcessor y Agentes
- Patrones de Concurrencia
Módulo 7: Acceso y Manipulación de Datos
Módulo 8: Pruebas y Depuración
- Pruebas Unitarias con NUnit
- Pruebas Basadas en Propiedades con FsCheck
- Técnicas de Depuración
- Perfilado de Rendimiento