Wenn ich asynchronen Code mit async / await schreibe, normalerweise ConfigureAwait(false)
um den Kontext nicht zu erfassen, springt mein Code nacheinander von einem Thread-Pool-Thread zum nächsten await
. Dies wirft Bedenken hinsichtlich der Gewindesicherheit auf. Ist dieser Code sicher?
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");
}
Die Variable i
ist ungeschützt und wird von mehreren Thread-Pool-Threads * aufgerufen. Obwohl das Zugriffsmuster nicht gleichzeitig ist, sollte es theoretisch möglich sein, dass jeder Thread einen lokal zwischengespeicherten Wert von erhöht i
, was zu mehr als 1.000.000 Iterationen führt. Ich kann dieses Szenario jedoch nicht in die Praxis umsetzen. Der obige Code wird auf meinem Computer immer in Ordnung gedruckt. Bedeutet dies, dass der Code threadsicher ist? Oder sollte ich den Zugriff auf die i
Variable mit a synchronisieren lock
?
(* Laut meinen Tests erfolgt durchschnittlich alle 2 Iterationen ein Thread-Wechsel.)
i
nach in jedem Thread zwischengespeichert? Sehen Sie sich dieses SharpLab IL an, um tiefer zu graben.