public async Task OnlyOneFactoryGetsCalledEvenInHighConcurrencyAsync(int accessorsCount) { using (var memoryCache = new MemoryCache(new MemoryCacheOptions())) { var cache = new CachingService(new MemoryCacheProvider(memoryCache)); cache.DefaultCachePolicy = new CacheDefaults { DefaultCacheDurationSeconds = 10 }; var factoryCallsCount = 0; var tasks = new ConcurrentBag <Task>(); Parallel.For(0, accessorsCount, _ => { var task = cache.GetOrAddAsync <int>( "foo", async _ => { Interlocked.Increment(ref factoryCallsCount); await Task.Delay(FactoryDuration).ConfigureAwait(false); return(42); } ); tasks.Add(task); }); await Task.WhenAll(tasks); Assert.Equal(1, factoryCallsCount); } }
public async Task LazyCache_MemoryProviderAsync() { var lazyCache = new CachingService(); await LoopActionAsync(Iterations, async() => { lazyCache.Add("TestKey", 123, TimeSpan.FromDays(1)); await lazyCache.GetAsync <int>("TestKey"); await lazyCache.GetOrAddAsync("TestKey", () => Task.FromResult("Hello World"), TimeSpan.FromDays(1)); }); }
public async Task <byte[]> Several_initializations_of_1Mb_object_with_200ms_delay() { var cache = new CachingService(new MemoryCacheProvider(new MemoryCache(new MemoryCacheOptions()))) as IAppCache; Task AddByteArrayToCache() => cache.GetOrAddAsync(CacheKey, async() => { await Task.Delay(200); return(await Task.FromResult(new byte[1024 * 1024])); // 1Mb }); // Even though the second and third init attempts are later, this whole operation should still take the time of the first var creationTask1 = AddByteArrayToCache(); // initialization attempt, or 200ms var creationTask2 = Delayed(50, AddByteArrayToCache); var creationTask3 = Delayed(50, AddByteArrayToCache); await Task.WhenAll(creationTask1, creationTask2, creationTask3); return(cache.Get <byte[]>(CacheKey)); }
public async Task LazyCacheCache() { using (var cache = new MemoryCache(new MemoryCacheOptions())) { var appcache = new CachingService(new MemoryCacheProvider(cache)); appcache.DefaultCachePolicy = new CacheDefaults { DefaultCacheDurationSeconds = (int)(CacheDuration.TotalSeconds) }; for (int i = 0; i < Rounds; i++) { var tasks = new ConcurrentBag <Task>(); FactoryCallsCount = 0; // FULL PARALLEL Parallel.ForEach(Keys, key => { Parallel.For(0, Accessors, _ => { var t = appcache.GetOrAddAsync <long>( key, async() => { Interlocked.Increment(ref FactoryCallsCount); await Task.Delay(FactoryDurationMs).ConfigureAwait(false); return(DateTimeOffset.UtcNow.Ticks); } ); tasks.Add(t); }); }); await Task.WhenAll(tasks).ConfigureAwait(false); UpdateExcessiveFactoryCallsStatistics(GetCallerName(), KeysCount, FactoryCallsCount); } cache.Compact(1); } }
static async Task Main(string[] args) { var cache = new CachingService(); var repository = new Repository(); var tasks = Enumerable.Range(0, 50) .Select(el => cache.GetOrAddAsync( /* Unique key */ $"{nameof(Repository)}.{nameof(Repository.GetList)}", /* method */ repository.GetList, /* time, by default 20 minutes */ TimeSpan.FromMinutes(30))); var lists = await Task.WhenAll(tasks); if (lists.SelectMany(el => el).Distinct().Count() > 1) { throw new Exception("Sample isn't relevant"); } Console.WriteLine("All great!"); }
public async Task LazyCache() { using (var cache = new MemoryCache(new MemoryCacheOptions())) { var appcache = new CachingService(new MemoryCacheProvider(cache)); appcache.DefaultCachePolicy = new CacheDefaults { DefaultCacheDurationSeconds = (int)(CacheDuration.TotalSeconds) }; for (int i = 0; i < Rounds; i++) { var tasks = new ConcurrentBag <Task>(); Parallel.ForEach(Keys, key => { Parallel.For(0, Accessors, _ => { var t = appcache.GetOrAddAsync <SamplePayload>( key, async() => { await Task.Delay(FactoryDurationMs).ConfigureAwait(false); return(new SamplePayload()); } ); tasks.Add(t); }); }); await Task.WhenAll(tasks).ConfigureAwait(false); } // CLEANUP cache.Compact(1); } }
public async Task GetOrAddFollowinGetOrAddAsyncReturnsTheFirstObjectAndUnwrapsTheFirstTask() { Func <Task <ComplexTestObject> > fetchAsync = () => Task.FromResult(testObject); Func <ComplexTestObject> fetchSync = () => new ComplexTestObject(); var actualAsync = await sut.GetOrAddAsync(TestKey, fetchAsync); var actualSync = sut.GetOrAdd(TestKey, fetchSync); Assert.IsNotNull(actualAsync); Assert.That(actualAsync, Is.EqualTo(testObject)); Assert.IsNotNull(actualSync); Assert.That(actualSync, Is.EqualTo(testObject)); Assert.AreEqual(actualAsync, actualSync); }
public async Task <T> GetOrAddAsync <T>(string key, Func <Task <T> > addItemFactory) { return(await _internalCache.GetOrAddAsync(key, addItemFactory).ConfigureAwait(false)); }
public Task <T> GetOrAddAsync <T>(string key, Func <Task <T> > addItemFactory) { return(_cachingService.GetOrAddAsync <T>(key, addItemFactory)); }
public async Task GetOrAddAsyncAndThenGetAsyncObjectReturnsCorrectType() { Func <Task <ComplexTestObject> > fetch = () => Task.FromResult(testObject); await sut.GetOrAddAsync(TestKey, fetch); var actual = await sut.GetAsync <ComplexTestObject>(TestKey); Assert.IsNotNull(actual); Assert.That(actual, Is.EqualTo(testObject)); }