class Program { static void Main(string[] args) { // This wont work... ////var obj = new object(); //// ////lock (obj) ////{ //// await TestLock(); ////} TestLock().GetAwaiter().GetResult(); } /// /// Test to see if this lock works /// /// An async task. public static async Task TestLock() { const int number = 10000; var someObject = new LockableObject(); var parallelSum = 0L; using (var barrier = new ManualResetEventSlim(false)) { var tasks = Enumerable.Range(0, number).Select(i => Task.Run(async () => { // Queue up everything behind this barrier so things try to do this all at once. barrier.Wait(); using (await someObject.GetLock(CancellationToken.None)) // Comment out this line to make it fail { // Critical Section var t = parallelSum; parallelSum = t + 1; } })); barrier.Set(); await Task.WhenAll(tasks); } if (parallelSum != number) { throw new Exception($"The counter is wrong. Expected {number}, but got {parallelSum}"); } } }