using System.Collections.Generic;
using System.Threading.Tasks;
public sealed class Runner
public static int TotalCount = 0;
private static ThreadLocal<Random> ThreadLocalRandom = new(() => new Random());
public async Task EnsureRunThingsExchangeAsync()
await Task.Delay(TimeSpan.FromMilliseconds(ThreadLocalRandom.Value.Next(0, 10)));
if (Interlocked.Increment(ref syncNum) > 1)
Interlocked.Exchange(ref syncNum, 1);
await ActualRunThingsAsync();
while (Interlocked.Decrement(ref syncNum) != 0);
private async Task ActualRunThingsAsync()
Interlocked.Increment(ref TotalCount);
public static async Task Main()
const int totalThreads = 10_000;
await Task.WhenAll(Enumerable.Range(0, totalThreads).Select(_ => r.EnsureRunThingsExchangeAsync()));
if (totalThreads != Runner.TotalCount)
Console.WriteLine($"Unexpected execution count. Found: {Runner.TotalCount}, expected: {totalThreads}.");
Console.WriteLine("Things worked according to plan!");