何时创建新任务

Mag*_*ind 7 .net c# asynchronous task-parallel-library async-await

我正在学习C#.NET 4.5中的任务并行,我对一个例子感到有些困惑.这是我不明白的代码:

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;
  });
}
Run Code Online (Sandbox Code Playgroud)

具体来说,我不明白他们为什么要包装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;
}
Run Code Online (Sandbox Code Playgroud)

两者有什么区别?哪一个更好?

Ste*_*ary 6

好吧,该示例专门展示了如何使用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;
}
Run Code Online (Sandbox Code Playgroud)

另请注意,该示例使用日期WebClient,应HttpClient在新代码中替换.

总的来说,它看起来只是一个不好的例子IMO.

  • @ach:每当我进行内存缓存时,我实际上更喜欢将`Task <T>`本身存储在缓存中,所以我会使用`ConcurrentDictionary <string,Task <string >>`来获取类似的方法这一般来说.如果我要为`Task.FromResult`编写一个例子,我会使用一个基类或接口,该方法返回一个`Task`,但实现是同步的; 我不会使用缓存作为此方法的示例.如果需要使用`await`关键字,则只应将方法标记为`async`. (2认同)