Я смотрел Зен асинхронный: лучшие практики для лучшей производительности и Стивен Тууб начал говорить о кешировании задач, где вместо кэширования результатов заданий задаются задачи кэширования самих задач. Насколько я понял, начинать новую задачу для каждой работы дорого, и ее нужно как можно меньше свести к минимуму. Примерно в 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 = 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();
}
Мне трудно понять, как это на самом деле помогает больше, чем просто хранить результаты.
Означает ли это, что вы используете меньше Заданий для получения данных?
А также, как мы узнаем, когда кешировать задачи? Насколько я понимаю, если вы кэшируете не то место, вы просто получаете нагрузку накладные расходы и слишком сильно нажимаете на систему.