Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When to Create a New Task

I am learning about Task Parallelism in C#.NET 4.5, and I am a little confused about an example. Here is the code I don't understand:

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;
  });
}

Specifically, I don't understand why they are wrapping DownloadStringTaskAsync() in another task. Isn't DownloadStringTaskAsync() already running on its own thread?

Here is the way I would have coded it:

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;
}

What is the difference between the two? Which one is better?

like image 655
MageWind Avatar asked Sep 10 '13 14:09

MageWind


People also ask

Is to do replacing tasks?

Microsoft introduced To Do to replace Wunderlist, a third-party app they acquired. Since then, To Do has become the replacement for the long-standing tasks section of Outlook. To Do allows the user to list and track their own personal tasks in lists and groups.


1 Answers

Well, the example is specifically showing how to use Task.FromResult, which your second code doesn't use. That said, I disagree with the usage of Task.Run in the example.

I'd write it like this, myself:

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;
}

Also note that the example uses the dated WebClient, which should be replaced with HttpClient in new code.

Overall, it just looks like a poor example IMO.

like image 77
Stephen Cleary Avatar answered Sep 16 '22 17:09

Stephen Cleary