Cuando escribo código asincrónico con async / await, generalmente ConfigureAwait(false)
para evitar capturar el contexto, mi código salta de un subproceso de grupo de subprocesos al siguiente después de cada uno await
. Esto plantea preocupaciones sobre la seguridad del hilo. ¿Es seguro este código?
static async Task Main()
{
int count = 0;
for (int i = 0; i < 1_000_000; i++)
{
Interlocked.Increment(ref count);
await Task.Yield();
}
Console.WriteLine(count == 1_000_000 ? "OK" : "Error");
}
La variable i
no está protegida y se accede a ella mediante múltiples subprocesos de grupo de subprocesos *. Aunque el patrón de acceso no es concurrente, debería ser teóricamente posible que cada subproceso incremente un valor almacenado localmente en caché i
, lo que da como resultado más de 1,000,000 de iteraciones. Sin embargo, no puedo producir este escenario en la práctica. El código anterior siempre imprime OK en mi máquina. ¿Esto significa que el código es seguro para subprocesos? ¿O debería sincronizar el acceso a la i
variable usando a lock
?
(* un cambio de hilo ocurre cada 2 iteraciones en promedio, de acuerdo con mis pruebas)
i
está en caché en cada hilo? Vea este SharpLab IL para profundizar.