我想知道检索以前缓存的对象的最佳方法是什么。
下面的代码可以工作,但是从字典中获取对象的位看起来可以做得更好。我觉得我可能会遗漏一些重要的事情。
public class ResourceProvider
{
private readonly IDictionary<string, string> _cachedResources;
public async Task<string> GetResource(string url)
{
// If there is a cached version use that
if (_cachedResources.ContainsKey(url))
{
// I am not sure this is the proper way if doing it
return await Task.Factory.StartNew(() => _cachedResources[url]);
}
// Get resource (i know httpclient is better as a static)
var resource = await new HttpClient().GetStringAsync(url);
_cachedResources.Add(url, resource);
return resource;
}
}
答案 0 :(得分:1)
一般情况下,我建议您使用IMemoryCache界面。因为您可以轻松地在内存缓存或redis缓存服务器(天蓝色)之间切换。这比家庭酿造解决方案更具优势。
用法非常简单。您只需按键缓存对象。密钥必须是唯一的,就像您在样本中所做的那样。您可以配置绝对或相对 到期,优先级和滑动到期,以便您可以根据需要进行操作。 它比简单的hashmap要好得多。
在本文中,How to use caching解释了如何将everthing设置为起点。
答案 1 :(得分:0)
可以根据需要多次等待任务。你可以这样做:
public class ResourceProvider
{
private readonly ConcurrentDictionary<string, Task<string>> cachedResources
= new ConcurrentDictionary<string, ValueTask<string>>();
public Task<string> GetResource(string url)
=> this.cachedResources.GetOrAdd(url, u => new new HttpClient().GetStringAsync(u));
}
由于您需要在大多数时间从缓存中获取值,现在有一个值任务(ValueTask<TResult> Struct):
public class ResourceProvider
{
private readonly ConcurrentDictionary<string, ValueTask<string>> cachedResources
= new ConcurrentDictionary<string, ValueTask<string>>();
public ValueTask<string> GetResource(string url)
=> this.cachedResources.GetOrAdd(
url,
u => new ValueTask<string>(new HttpClient().GetStringAsync(u)));
}