我正在观看异步之禅:最佳性能的最佳实践,Stephen Toub开始谈论任务缓存,即不是缓存任务工作的结果,而是缓存任务本身。据我所知,为每个工作启动一个新任务很昂贵,应尽可能将其最小化。在约28:00处,他展示了这种方法:
private static ConcurrentDictionary<string, string> s_urlToContents;
public static async Task<string> GetContentsAsync(string url)
{
string contents;
if(!s_urlToContents.TryGetValue(url, out contents))
{
var response = await new HttpClient().GetAsync(url);
contents = response.EnsureSuccessStatusCode().Content.ReadAsString();
s_urlToContents.TryAdd(url, contents);
}
return contents;
}
这个方法一开始看起来很好,它可以缓存结果。但我甚至没有想到获取内容的工作也可以被缓存。
然后他展示了这种方法:
private static ConcurrentDictionary<string, Task<string>> s_urlToContents;
public static Task<string> GetContentsAsync(string url)
{
Task<string> contents;
if(!s_urlToContents.TryGetValue(url, out contents))
{
contents = GetContentsAsync(url);
contents.ContinueWith(t => s_urlToContents.TryAdd(url, t); },
TaskContinuationOptions.OnlyOnRanToCompletion |
TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Default);
}
return contents;
}
private static async Task<string> GetContentsAsync(string url)
{
var response = await new HttpClient().GetAsync(url);
return response.EnsureSuccessStatusCode().Content.ReadAsString();
}
我很难理解这种方法如何有助于不仅仅是存储结果。
这是否意味着您使用更少的任务来获取数据?
另外,我们如何知道何时缓存任务?据我所知,如果您在错误的位置进行缓存,只会增加大量开销并过度压力系统。