Add Glav.CacheAdapter.Core.CacheProvider.GetAsync

Issue #27 resolved
ckknight
created an issue

It would be nice to be able to use the CacheProvider asynchronously, so the underlying cache will be accessed and if the value is null, instead of calling Func<T> getData, it could call Func<Task<T>> getDataAsync, and await on that.

Comments (16)

  1. Paul Glavich repo owner

    I have been thinking about this exact same thing actually. Great suggestion. I am planning on formalising the next release (currently in beta) and will release that first, then look at introducing the async functionality.

  2. Khader Alatrash

    I got the code and added the following 2 new ASYNC methods to the ICacheProvider with implementation in CacheProvider (Note: I had to change to use .NET 4.5 and hence remove the Microsoft.Bcl.* from the dependent packages). Would you please add them to the package and create a new release?

    public Task<T> GetAsync<T>(string cacheKey, DateTime expiryDate, Func<Task<T>> getData, string parentKey = null, CacheDependencyAction actionForDependency = CacheDependencyAction.ClearDependentItems) where T : class
    {
        return GetAndAddIfNecessaryAsync(cacheKey,
            data =>
            {
                _cache.Add(cacheKey, expiryDate, data);
                _logger.WriteInfoMessage(string.Format("Adding item [{0}] to cache with expiry date/time of [{1}].", cacheKey,
                                                       expiryDate.ToString("dd/MM/yyyy hh:mm:ss")));
            },
            getData,
            parentKey,
            actionForDependency
            );
    }
    
    public Task<T> GetAsync<T>(string cacheKey, TimeSpan slidingExpiryWindow, Func<Task<T>> getData, string parentKey = null, CacheDependencyAction actionForDependency = CacheDependencyAction.ClearDependentItems) where T : class
    {
        return GetAndAddIfNecessaryAsync(cacheKey,
            data =>
            {
                _cache.Add(cacheKey, slidingExpiryWindow, data);
                _logger.WriteInfoMessage(
                    string.Format("Adding item [{0}] to cache with sliding sliding expiry window in seconds [{1}].", cacheKey,
                                  slidingExpiryWindow.TotalSeconds));
            },
            getData,
            parentKey,
            actionForDependency
            );
    }
    
    private async Task<T> GetAndAddIfNecessaryAsync<T>(string cacheKey, Action<T> addData, Func<Task<T>> getData, string parentKey = null, CacheDependencyAction actionForDependency = CacheDependencyAction.ClearDependentItems) where T : class
    {
        if (!_config.IsCacheEnabled)
            return await getData();
    
        //Get data from cache
        T data = _cache.Get<T>(cacheKey);
    
        // check to see if we need to get data from the source
        if (data == null)
        {
            //get data from source
            data = await getData();
    
            //only add non null data to the cache.
            if (data != null)
            {
                addData(data);
                ManageCacheDependenciesForCacheItem(data, cacheKey, parentKey, actionForDependency);
            }
        }
        else
        {
            _logger.WriteInfoMessage(string.Format("Retrieving item [{0}] from cache.", cacheKey));
        }
    
        return data;
    }
    
  3. Paul Glavich repo owner

    Sorry my bad. I have done the merge and was doing a few extra minor bug fixes, then got distracted with some family issues.

    My apologies. I will get this out soon.

  4. Paul Glavich repo owner

    Just FYI. Everything is merged and I have added a few tests and found a few issues so am fixing those, doing some more cleanup and should be ready soon.

  5. Paul Glavich repo owner

    Yes. It was one if the changes as part of your PULL request which I have merged in (manually due to some conflicts) and will form part of the next release.

  6. Log in to comment