【发布时间】: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<List<TItem>>。 -
我刚刚编辑了我的第一条评论。我会传递一个 Func,它仅在缓存未命中时创建列表。
-
顺便说一句:你到处混用同步和异步。尝试“一直异步”。否则,您迟早会冒着被一些死锁问题绊倒的风险。我还建议不要一直创建新的 HttpClients。使用 HttpClientFactory 和 DI(如果可以的话)。
-
顺便说一句:您可能还想探索波莉的CachePolicy?
标签: c# caching dotnet-httpclient http-caching