I was watching The zen of async: Best practices for best performance and Stephen Toub started to talk about Task caching, where instead of caching the results of task jobs you cache the tasks themselves. As far as i understood starting a new task for every job is expensive and it should be minimized as much as possible. At around 28:00 he showed this method:
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;
}
Which at a first look looks like a good thought out method where you cache results, i didn't event think about caching the job of getting the contents.
And than he showed this method:
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();
}
I have trouble understanding how this actually helps more than just storing the results.
Does this mean that you're using less Tasks to get the data?
And also, how do we know when to cache tasks? As far as i understand if you're caching in the wrong place you just get a load of overhead and stress the system too much
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…