public async Task GetOrAdd_ExtentionMethod_protected_from_running_twice_in_multi_threaded_code() { var cache = new MultiThreadProtectedDecorator(new SimpleInmemoryCache()); int ctorCallCount = 0; Func <string, int> ctor = _ => { Interlocked.Increment(ref ctorCallCount); return(ctorCallCount); }; Task <int> t1 = Task.Run(() => cache.GetOrAdd("Key", ctor)); Task <int> t2 = Task.Run(() => cache.GetOrAdd("Key", ctor)); await Task.WhenAll(t1, t2); Assert.That(ctorCallCount, Is.EqualTo(1)); }
public async Task GetOrAdd_protected_from_running_twice_in_multi_threaded_code() { var cache = new MultiThreadProtectedDecorator(new SimpleInmemoryCache()); int ctorCallCount = 0; Func <string, int> slowCtor = _ => { // slow down the first ctor call to ensure second thread always see the cache // as empty even though this ctor has been called to add the item Thread.Sleep(TimeSpan.FromMilliseconds(100)); Interlocked.Increment(ref ctorCallCount); return(ctorCallCount); }; Func <string, int> ctor = _ => { Interlocked.Increment(ref ctorCallCount); return(ctorCallCount); }; Task <int> t1 = Task.Run(() => cache.GetOrAdd("Key", slowCtor)); Task <int> t2 = Task.Run(() => cache.GetOrAdd("Key", ctor)); await Task.WhenAll(t1, t2); Assert.That(ctorCallCount, Is.EqualTo(1)); }