Código asíncrono y reactivo
Funciones async, await y tareas, y campos reactivos, valores calculados y efectos en Antril.
En esta página
async y await
Una función marcada con async devuelve un Task (sin resultado) o un Task<T>. Dentro de ella, await espera a otra tarea sin bloquear a las demás; la función continúa donde se detuvo cuando esa tarea termina.
import System;
import System.Threading.Tasks;
into namespace Jobs
{
async Fetch(i32 id) : Task<i32>
{
await Task.Delay(10);
return id * 10;
}
async Total() : Task<i32>
{
i32 a = await Fetch(1);
i32 b = await Fetch(2);
return a + b;
}
async Tick(str name, i32 times) : Task
{
loop (i32 i = 0..times)
{
Console.WriteLine(name + " " + i);
await Task.Yield();
}
}
Main()
{
Console.WriteLine(Total().Result);
Task[] both = [Tick("a", 2), Tick("b", 2)];
Task.WhenAll(both).Wait();
}
}
larva run
30
a 0
b 0
a 1
b 1
asyncse usa en funciones libres y en métodos de clases.awaitsolo se permite dentro de una funciónasync.Task<T>necesita unTque se pueda copiar (T : copy).- Las funciones asíncronas se turnan en un solo hilo:
System.Threading.Tasks.Schedulerejecuta lo que esté listo, y los temporizadores. Wait()bloquea hasta que una tarea termina, yResultespera y entrega su valor. Úsalos donde no estés dentro de una funciónasync, como enMain.
Miembro de Task |
Qué hace |
|---|---|
Task.Delay(ms) |
Una tarea que termina después de ms milisegundos. |
Task.Yield() |
Deja que otras tareas se ejecuten antes de continuar. |
Task.WhenAll(tasks) |
Una tarea que termina cuando todas las de tasks han terminado. |
Task<T>.FromResult(value) |
Un Task<T> que ya está completo. |
Task.Run(f), Task.Run<T>(f) |
Una tarea que ejecuta la función f. |
Wait(), Result, IsCompleted, IsFaulted |
Esperar una tarea y consultar su estado. |
Excepciones
Una excepción lanzada en una función async se guarda en su tarea. await, Wait() y Result la vuelven a lanzar, tal como era:
import System;
import System.Threading.Tasks;
async Failing() : Task<i32>
{
await Task.Yield();
throw new InvalidOperationError("no data");
}
async Rescue() : Task<i32>
{
try
{
return await Failing();
}
catch (InvalidOperationError e)
{
Console.WriteLine("failed: " + e.Message);
return -1;
}
}
Main()
{
Console.WriteLine(Rescue().Result);
}
larva run
failed: no data
-1
Para trabajar en varios hilos a la vez, consulta System.Threading en la descripción general de la biblioteca.
Código reactivo
Las clases pueden tener estado reactivo: campos que notan cuándo se leen y cuándo cambian, de modo que el código que depende de ellos se vuelve a ejecutar solo.
| Declaración | Qué es |
|---|---|
reactive i32 count = 0; |
Un campo que es una señal. Leerlo dentro de un efecto hace que el efecto dependa de él; asignarlo vuelve a ejecutar esos efectos. |
computed i32 Double => count * 2; |
Un valor calculado a partir de otros. Quien lo lee depende de lo que él lee. |
effect { … } |
Se ejecuta ahora y otra vez cada vez que cambia algo que leyó. Entrega un System.Reactive.Effect; Dispose() lo detiene. |
reacts Log() { … } |
Un método que se ejecuta como efecto una vez que su objeto está construido. |
import System;
import System.Reactive;
into namespace Ui
{
public class Cart
{
public:
reactive i32 items = 0;
reactive f64 price = 2.5;
computed f64 Total => items * price;
reacts Log()
{
Console.WriteLine("items: " + items);
}
}
Main()
{
Cart cart = new Cart();
Effect shown = effect { Console.WriteLine("total: " + cart.Total); };
cart.items = 2;
Reactive.Batch(() => { cart.items = 3; cart.price = 4.0; });
shown.Dispose();
cart.items = 10;
}
}
larva run
items: 0
total: 0
items: 2
total: 5
items: 3
total: 12
items: 10
Reactive.Batch(f)ejecutafy después cada efecto afectado una sola vez, en lugar de una vez por cambio.- Un efecto no se vuelve a ejecutar mientras se está ejecutando, así que un efecto que escribe lo que lee no entra en un ciclo.
- Un efecto ve las variables locales que usa tal como están cuando se ejecuta, igual que una lambda.
- Los miembros reactivos pertenecen a las clases, no a los tipos
value.
Siguiente: la referencia, que describe en detalle cada construcción del lenguaje.
Editar esta página en GitHub Reportar un problema