public void AddAndReplaceEntries_AreThreadSafe() { var cache = new ApplicationCache( new CacheOptions { MemoryCacheOptions = new MemoryCacheOptions { ExpirationScanFrequency = TimeSpan.Zero, SizeLimit = 20, CompactionPercentage = 0.5 } }); var cts = new CancellationTokenSource(); var random = new Random(); var task0 = Task.Run(() => { while (!cts.IsCancellationRequested) { var entrySize = random.Next(0, 5); cache.Set <object>(new ApplicationKey(random.Next(0, 10).ToString()), entrySize, new MemoryCacheEntryOptions { Size = entrySize }); } }); var task1 = Task.Run(() => { while (!cts.IsCancellationRequested) { var entrySize = random.Next(0, 5); cache.Set <object>(new ApplicationKey(random.Next(0, 10).ToString()), entrySize, new MemoryCacheEntryOptions { Size = entrySize }); } }); var task2 = Task.Run(() => { while (!cts.IsCancellationRequested) { var entrySize = random.Next(0, 5); cache.Set <object>(new ApplicationKey(random.Next(0, 10).ToString()), entrySize, new MemoryCacheEntryOptions { Size = entrySize }); } }); cts.CancelAfter(TimeSpan.FromSeconds(5)); var task3 = Task.Delay(TimeSpan.FromSeconds(7)); Task.WaitAll(task0, task1, task2, task3); Assert.Equal(TaskStatus.RanToCompletion, task0.Status); Assert.Equal(TaskStatus.RanToCompletion, task1.Status); Assert.Equal(TaskStatus.RanToCompletion, task2.Status); Assert.Equal(TaskStatus.RanToCompletion, task3.Status); Assert.InRange(cache.Count(), 0, 20); }