Async/Await (Parte 3 de 11)
1Paralelización con async let
2Calcular tiempo de ejecución de un código
3¿Qué es un Task?
4¿Qué es un Actor y para que se utilizan?
5¿Qué es Main Actor?
6Modificador task
7Cómo utilizar Task Group
8Trabajando con iteraciones asíncronas usando AsyncSequence
9Mezclando código síncrono y asíncrono usando CheckedContinuation
10Optimiza la eficiencia de tu código concurrente con DiscardingTaskGroup
11Explorando Task-local
¿Qué es un Task?

Libranner Santos
13 marzo, 20233min de lectura
Task
representa la unidad mínima de código asíncrono.
Si tenemos una función síncrona, pero queremos ejecutar código asíncrono dentro de la misma, podemos usar Task
. Por ejemplo:
func sync() {executeProcess()Task {await callAsynchronous()}executeOtherProcess()}
¿Cómo cancelar un Task?
Cuando creamos un Task
podemos guardar una referencia a la misma en caso de que queramos poder cancelarla luego.
let task = Task {await callAsynchronous()}task.cancel()
En este caso, guardamos una referencia al objeto en task
y luego ejecutamos cancel()
.
Puedes utilizar la propiedad Task.isCancelled
para saber si una tarea ya ha sido cancelada. De la misma forma puedes ejecutar Task.checkCancellation()
, el cual devuelve un CancellationError
si la tarea ya ha sido cancelada.
El siguiente código verifica si la tarea ha sido cancelada antes de ejecutarse:
func generate() -> Int async {... // Código de procesamientoif Task.isCancelled { return 0 }... // Más código de procesamiento}
Al verificar Task.isCancelled
antes de ejecutar cualquier código que deba ser procesado, nos ahorramos el costo de ese procesamiento si la tarea ha sido cancelada, ya que no será necesario llevarlo a cabo.
Otra manera es usando withTaskCancellationHandler(operation:onCancel:)
. Este ejecuta una tarea, pero puedes pasar un bloque de código que se ejecutará cuando la tarea sea cancelada.
func start() async {await withTaskCancellationHandler {await generate()} onCancel: {debugPrint("Tarea cancelada")}}
En este caso si se cancela la tarea creada cuando ejecutamos generate()
. Se ejecutará lo que pongamos en onCancel
, en este caso imprimirá el mensaje Tarea cancelada
en consola.
Establecer la prioridad de un Task
Si consultamos la documentación para Task
, veremos que acepta los parámetros priority
y operation
: Task(priority:operation)
.
priority
indica la prioridad del Task
. Esto puede afectar el orden en que se ejecuta nuestro código con respecto a otras tareas asíncronas. Un Task
por defecto hereda la prioridad del contexto donde se ejecuta.
Las diferentes prioridades por las que podemos optar son:
- Background
- High
- Low
- Medium
- UserInitiated
- Utility
Para indicar la prioridad solo necesitamos pasar el valor cuando instanciamos el objeto, ejemplo:
let task = Task(priority: .high) {// ...}
En este caso indicamos que la prioridad high
. Es necesario saber que asignar una prioridad alta no quiere decir que nuestro código se ejecutará inmediatamente. El Executor
decidirá el orden de ejecución, tomando en cuenta todas las tareas en cola.
Puedes consultar la prioridad de una tarea usando Task.currentPriority
. Por defecto cuando creamos un Task
este hereda la prioridad del contexto donde se crea. ¿Y qué si no queremos heredar la prioridad? Utilizamos tareas desacopladas.
Utilizando Tareas Desacopladas (Detached Task)
Si no quieres heredar el contexto donde ejecutas un Task
, debes usar Task.detached(priority:operation)
. Este constructor es muy similar al que utilizamos con Task(priority:operation)
anteriormente, solo que en este caso la tarea creada no hereda el contexto donde es creada.
Task.detached(priority: .background) {// ...}
Async/Await (Parte 3 de 11)
1Paralelización con async let
2Calcular tiempo de ejecución de un código
3¿Qué es un Task?
4¿Qué es un Actor y para que se utilizan?
5¿Qué es Main Actor?
6Modificador task
7Cómo utilizar Task Group
8Trabajando con iteraciones asíncronas usando AsyncSequence
9Mezclando código síncrono y asíncrono usando CheckedContinuation
10Optimiza la eficiencia de tu código concurrente con DiscardingTaskGroup
11Explorando Task-local