Exemple #1
0
        /// <summary>
        /// Read a value from the cache
        /// </summary>
        /// <typeparam name="T">Type to read</typeparam>
        /// <param name="key">Key</param>
        /// <param name="value">Value</param>
        /// <param name="notFound">Create T if not found, null to not do this. Item1 = value, Item2 = expiration.</param>
        public async Task <CachedItem <T> > Get <T>(string key, Func <Task <CachedItem <T> > > notFound) where T : class
        {
            using (var lockRead = cacheTimerLock.LockRead())
            {
                if (cache.TryGetValue(key, out KeyValuePair <DateTime, object> cacheValue))
                {
                    return(new CachedItem <T>((T)cacheValue.Value, cacheValue.Key));
                }
            }

            // most likely the callback needs to make a network request, so don't do it in a lock
            // it's ok if multiple calls stack on the same cache key, the last one to finish will win
            CachedItem <T> newItem = await notFound();

            // don't add null values to the cache
            if (newItem.Value != null)
            {
                using (var lockWrite = cacheTimerLock.LockWrite())
                {
                    cache[key] = new KeyValuePair <DateTime, object>(newItem.Expiration, newItem.Value);
                }
            }

            return(newItem);
        }