【问题标题】:Caching not stored using Microsoft.Extensions.Caching.Memory in DOT NET在 DOT NET 中未使用 Microsoft.Extensions.Caching.Memory 存储缓存
【发布时间】:2020-12-15 01:10:14
【问题描述】:

我正在使用 Microsoft Extensions Caching Memory,但它没有将数据存储在缓存中。 我的代码:

public class MyMemoryCache<TItem>
    {
        private MemoryCache _cache = new MemoryCache(new MemoryCacheOptions());
        private ConcurrentDictionary<object, SemaphoreSlim> _locks = new ConcurrentDictionary<object, SemaphoreSlim>();
        public async Task<List<TItem>> GetOrCreate(object key, List<TItem> createItem)
        {
            List<TItem> cacheEntry;
            if (!_cache.TryGetValue(key, out cacheEntry))
            {
                SemaphoreSlim mylock = _locks.GetOrAdd(key, k => new SemaphoreSlim(1, 1));
 
                await mylock.WaitAsync();
                try
                {
                    if (!_cache.TryGetValue(key, out cacheEntry))
                    {
                        // Key not in cache, so get data.
                        cacheEntry = createItem;
                        _cache.Set(key, cacheEntry);
                    }
                }
                finally
                {
                    mylock.Release();
                }
            }

            return cacheEntry;
        }
    }

实施

ISqlQueries query = new SqlQueries();    
var _openCases = new MyMemoryCache<MyListDTO>();
var openedCases = _openCases.GetOrCreate("GetMyInfo", query.Displaydata()).Result;

查询

public List<MyListDTO> DisplayData()
{
     HttpClientHandler hch = new HttpClientHandler();
     hch.Proxy = null;
     hch.UseProxy = false;
     var client = new HttpClient(hch);
     var result = client.GetAsync(url, HttpCompletionOption.ResponseHeadersRead).Result;
}

我能够从服务器成功检索数据,但由于缺少缓存存储,它一直在调用服务器。我错过了什么,谢谢。

【问题讨论】:

  • query.DisplayData() 被评估,然后其结果被传递给GetOrCreate。所以,是的,无论缓存如何,它都会每次都执行。为防止这种情况发生,您可能希望改为传递 Func&lt;List&lt;TItem&gt;&gt;
  • 我刚刚编辑了我的第一条评论。我会传递一个 Func,它仅在缓存未命中时创建列表。
  • 顺便说一句:你到处混用同步和异步。尝试“一直异步”。否则,您迟早会冒着被一些死锁问题绊倒的风险。我还建议不要一直创建新的 HttpClients。使用 HttpClientFactory 和 DI(如果可以的话)。
  • 顺便说一句:您可能还想探索波莉的CachePolicy

标签: c# caching dotnet-httpclient http-caching


【解决方案1】:

我会像这样更改代码:

public async Task<List<TItem>> GetOrCreate(object key, Func<Task<List<TItem>>> createItem)
{
    List<TItem> cacheEntry;
    if (!_cache.TryGetValue(key, out cacheEntry))
    {
        SemaphoreSlim mylock = _locks.GetOrAdd(key, k => new SemaphoreSlim(1, 1));

        await mylock.WaitAsync();
        try
        {
            if (!_cache.TryGetValue(key, out cacheEntry))
            {
                // Key not in cache, so get data.
                cacheEntry = await createItem(); // will only actually fetch data
                                                 // on cache miss
                _cache.Set(key, cacheEntry);
            }
        }
        finally
        {
            mylock.Release();
        }
    }

    return cacheEntry;
}

用法:

var openedCases = await _openCases.GetOrCreate("GetMyInfo", () => query.Displaydata());

查询:

public async Task<List<MyListDTO>> DisplayData()
{
     HttpClientHandler hch = new HttpClientHandler();
     hch.Proxy = null;
     hch.UseProxy = false;
     var client = new HttpClient(hch);
     // ^^ Please do NOT create new HttpClients all the time.

     return await client.GetAsync(url,HttpCompletionOption.ResponseHeadersRead);
}

【讨论】:

  • 嗨,现在它首先进入缓存方法并命中 cache.set 但再次没有保存它,因为我刷新页面并仍然调用服务器。
  • 嗯,...实际上,我没有找到需要键值的Set 重载。唯一的 2-Args Set 需要一个 CacheItem 和一个 Policy...
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-03-27
  • 1970-01-01
  • 2021-08-09
  • 2014-08-18
  • 2015-09-19
  • 2017-05-16
  • 2020-11-03
相关资源
最近更新 更多