public static string GetTestDataWithCaching(string key, CacheItemPolicy overrideCacheItemPolicy = null) { return(TestCacheFacade.GetCachedData(new TestCacheParams(key, overrideCacheItemPolicy), () => { return SomeLongRunningMethod(DateTime.Now); })); }
public static string GetTestDataWithCachingAndTTL(string key, int secondsTTL) { return(TestCacheFacade.GetCachedData( new TestCacheParams(key, secondsTTL), () => { return SomeLongRunningMethod(DateTime.Now); } )); }
public async Task TestCacheThreadSafetyWithLazyInitialization() { string key = $"CachedDataWithSameKey[{nameof(TestCacheThreadSafetyWithLazyInitialization)}]"; int secondsTTL = 300; int threadCount = 20; var globalCount = 0; var timer = Stopwatch.StartNew(); var tasks = new List <Task <string> >(); for (int x = 0; x < threadCount; x++) { //Simulated MANY threads running at the same time attempting to get the same data for the same Cache key!!! tasks.Add(Task.Run(() => { //THIS RUNS ON IT'S OWN THREAD, but the Lazy Cache initialization will ensure that the Value Factory Function // is only executed by the FIRST thread, and all other threads will immediately benefit from the result! return(TestCacheFacade.GetCachedData(new TestCacheParams(key, secondsTTL), () => { //TEST that this Code ONLY ever runs ONE TIME by ONE THREAD via Lazy<> initialization! // meaning globalCount is only ever incremented 1 time! Interlocked.Increment(ref globalCount); //TEST that the cached data is never re-generated so only ONE Value is ever created! var longTaskResult = SomeLongRunningMethod(DateTime.Now); return longTaskResult; })); })); } //Allow all threads to complete and get the results... var results = await Task.WhenAll(tasks.ToArray()); var distinctCount = results.Distinct().Count(); timer.Stop(); //TEST that this Code ONLY ever runs ONE TIME by ONE THREAD via Lazy<> initialization! // meaning globalCount is only ever incremented 1 time! Assert.AreEqual(1, globalCount); //Ensure ONLY ONE item was ever generated and ALL other's were identical from Cache! Assert.AreEqual(1, distinctCount); //Ensure that the Total time takes barely longer than one iteration of the Long Running Task! Assert.IsTrue(timer.ElapsedMilliseconds < (LongRunningTaskMillis * 2)); }