Exemple #1
0
        /// <summary>
        /// Gets a data from cache if possible, otherwise from original source then sets cache.
        /// </summary>
        /// <typeparam name="T">Targeted data type.</typeparam>
        /// <param name="cache">Cache provider.</param>
        /// <param name="cacheKey">Cache key.</param>
        /// <param name="options">Cache options.</param>
        /// <param name="getWithoutCacheDelegate">Delegate to retrieve data from the original source.</param>
        /// <returns>The data.</returns>
        internal static async Task <T> GetOrSetFromCache <T>(
            this IDistributedCache cache,
            string cacheKey,
            DistributedCacheEntryOptions options,
            Func <Task <T> > getWithoutCacheDelegate)
            where T : class, new()
        {
            T datas = await cache.GetFromCache <T>(cacheKey).ConfigureAwait(false);

            if (datas == null)
            {
                SemaphoreSlim semaphore = _semaphores.GetOrAdd(cacheKey, new SemaphoreSlim(1, 1));
                await semaphore.WaitAsync().ConfigureAwait(false);

                try
                {
                    datas = await cache.GetFromCache <T>(cacheKey).ConfigureAwait(false);

                    if (datas == null)
                    {
                        datas = await getWithoutCacheDelegate().ConfigureAwait(false);

                        if (datas != null)
                        {
                            await cache.SetAsync(cacheKey, Serialize(datas), options).ConfigureAwait(false);
                        }
                    }
                }
                finally
                {
                    semaphore.Release();
                }
            }

            return(datas);
        }