示例#1
0
        /// <summary>
        /// Gets an item from cache or calls the callback method and stores the result in the cache
        /// </summary>
        /// <typeparam name="T">The return type</typeparam>
        /// <param name="key">The key of the item in the cache</param>
        /// <param name="getItemDelegate">Delegate callback to get the item if needed</param>
        /// <param name="duration">The duration in seconds to store the item in the cache</param>
        /// <returns>The cached item or result of the callback if item is not in the cache</returns>
        public T Get <T>(string key, Func <T> getItemDelegate, int duration) where T : class
        {
            lock (SyncObject)
            {
                var cache = GetCache();

                var item = cache.Get(key) as T;

                if (item != null)
                {
                    return(item);
                }

                item = getItemDelegate();

                cache.Add(key, item, DateTime.Now.AddSeconds(duration));
                if (!RetainCacheDurationDetail)
                {
                    return(item);
                }

                var cacheDetail = new CacheItemDetail
                {
                    AddedOn  = DateTime.Now,
                    Duration = duration
                };

                cache.Add($"{key}{CacheKeyDurationSuffix}", cacheDetail, DateTime.Now.AddSeconds(duration));
                return(item);
            }
        }
示例#2
0
        private async Task <T> RunFactory <T, TParam>(ObjectCache cache, string key, Func <TParam, Task <T> > getItemFactory, TParam inputParam, int duration) where T : class
        {
            await PurgeOldLocks();

            var cacheLock = Locks.GetOrAdd(key, k => new SemaphoreSlim(1));

            try
            {
                //Wait for anyone currently running the factory.
                await cacheLock.WaitAsync();

                //Check to see if another factory has already ran while we waited.
                var oldResult = (T)cache.Get(key);
                if (oldResult != null)
                {
                    return(oldResult);
                }

                //Run the factory then cache the result.
                var newResult = await getItemFactory(inputParam);

                cache.Add(key, newResult, DateTime.Now.AddSeconds(duration));

                if (!RetainCacheDurationDetail)
                {
                    return(newResult);
                }

                var cacheDetail = new CacheItemDetail
                {
                    AddedOn  = DateTime.Now,
                    Duration = duration
                };

                cache.Add($"{key}{CacheKeyDurationSuffix}", cacheDetail, DateTime.Now.AddSeconds(duration));

                return(newResult);
            }
            finally
            {
                cacheLock.Release();
            }
        }