Apariencia
Concurrencia y ciclo de vida
Primitivas disponibles
| Tipo | Propósito | Entrada |
|---|---|---|
AsyncLock | Una operación a la vez | LockAsync |
AsyncSemaphore | Número limitado de operaciones | WaitAsync |
AsyncReaderWriterLock | Lectores y escritor exclusivo | ReadLockAsync, WriteLockAsync |
AsyncMonitor | Espera y señalización | EnterAsync, WaitAsync, Pulse, PulseAll |
AsyncLifetime | Admisión y detención coordinadas | Acquire, TryBeginStop, WhenIdle |
Las adquisiciones devuelven liberadores que deben usarse con using. Los métodos de espera aceptan cancelación.
Exclusión mutua
csharp
using Greencore.Platform.Concurrency;
using var puerta = new AsyncLock();
var contador = 0;
await Task.WhenAll(Incrementar(), Incrementar());
Console.WriteLine(contador); // 2
async Task Incrementar()
{
using var permiso = await puerta.LockAsync();
await Task.Yield();
contador++;
}Comparte la misma instancia entre operaciones que protegen el mismo recurso. Crear un lock distinto por llamada no coordina esas llamadas.
Cierre ordenado
csharp
using Greencore.Platform.Concurrency.Lifetime;
await using var vida = new AsyncLifetime();
using (var permiso = vida.Acquire())
{
Console.WriteLine("Operación admitida.");
}
vida.TryBeginStop();
await vida.WhenIdle;
Console.WriteLine("Sin operaciones activas.");Al comenzar la detención se rechazan nuevos permisos y se cancela StoppingToken. WhenIdle se completa después de iniciar la detención y liberar todos los permisos existentes; no representa cada intervalo sin actividad durante el estado activo.
No esperes DisposeAsync, Dispose o WhenIdle mientras conservas un permiso que impide terminar. El propietario sigue siendo responsable del cierre funcional y del drenaje de sus datos.