2013-09-10 5 views
7

Я узнаю о параллелизме задач в C# .NET 4.5, и я немного смущен о example. Вот код, который я не понимаю:Когда создавать новую задачу

public static Task<string> DownloadStringAsync(string address) 
{ 
    // First try to retrieve the content from cache. 
    string content; 
    if (cachedDownloads.TryGetValue(address, out content)) 
    { 
    return Task.FromResult<string>(content); 
    } 

    // If the result was not in the cache, download the 
    // string and add it to the cache. 
    return Task.Run(async() => // why create a new task here? 
    { 
    content = await new WebClient().DownloadStringTaskAsync(address); 
    cachedDownloads.TryAdd(address, content); 
    return content; 
    }); 
} 

В частности, я не понимаю, почему они оборачивают DownloadStringTaskAsync() в другой задаче. Разве не DownloadStringTaskAsync() уже работает в своей собственной теме?

Вот как я бы закодировал:

public static async Task<string> DownloadStringAsync(string address) 
{ 
    // First try to retrieve the content from cache. 
    string content; 
    if (cachedDownloads.TryGetValue(address, out content)) 
    { 
     return content; 
    } 

    // If the result was not in the cache, download the 
    // string and add it to the cache. 
    content = await new WebClient().DownloadStringTaskAsync(address); 
    cachedDownloads.TryAdd(address, content); 
    return content; 
} 

В чем разница между ними? Какая из них лучше?

+0

Бывший работает над несколькими потоками последнего нет (поскольку, вероятно, WebClient.DownloadStringTaskAsync не использует Task.Run, обратите внимание, что второе должно быть предпочтительным, так как пользователь не ожидает появления нового потока при использовании метода async –

ответ

5

Ну, пример показывает, как использовать Task.FromResult, который ваш второй код не использует. Тем не менее, я не согласен с использованием Task.Run в этом примере.

Я бы написать это, я:

public static Task<string> DownloadStringAsync(string address) 
{ 
    // First try to retrieve the content from cache. 
    string content; 
    if (cachedDownloads.TryGetValue(address, out content)) 
    { 
    return Task.FromResult(content); 
    } 

    // If the result was not in the cache, download the 
    // string and add it to the cache. 
    return DownloadAndCacheStringAsync(address); 
} 

private static async Task<string> DownloadAndCacheStringAsync(string address) 
{ 
    var content = await new WebClient().DownloadStringTaskAsync(address); 
    cachedDownloads.TryAdd(address, content); 
    return content; 
} 

отметить также, что в данном примере используется датированную WebClient, который должен быть заменен HttpClient в новом коде.

В целом, это похоже на плохой пример ИМО.

+0

Когда вы говорите, что вы бы это записывали, вы имеете в виду пример ИЛИ такой метод в целом? Какие факторы ускорили бы решение не помечать метод async при возврате задачи и выполнении асинхронных операций? Спасибо. –

+2

@ach: всякий раз, когда я делаю кеш в памяти, я фактически предпочитаю хранить 'Task ' сам в кеше, поэтому я бы использовал строку 'ConcurrentDictionary <, Задача >' для такого метода в целом Если бы я написал пример для 'Task.FromResult', я бы использовал базовый класс или interfac e, где метод возвращает «Задача», но реализация является синхронной; Я бы не использовал кеш в качестве примера этого метода. Вы должны пометить метод как 'async', если ему нужно использовать ключевое слово' await'. –

Смежные вопросы