组合任务会产生字典

Ste*_*e B 0 c# task

我正在尝试并行化依赖外部资源的工作,并将其组合成一个结果字典.

为了说明我的需要,想象一下我想下载一组文件,并将每个结果放在一个字典中,其中键是url:

string[] urls = { "http://msdn.microsoft.com", "http://www.stackoverflow.com", "http://www.google.com" };

var fileContentTask = GetUrls(urls);

fileContentTask.Wait();

Dictionary<string, string> result = fileContentTask.Result;
// Do something
Run Code Online (Sandbox Code Playgroud)

但是,我能够编码GetUrls方法.我可以生成所有任务,但我没有找到如何在字典中合并结果:

static Task<Dictionary<string,string>> GetUrls(string[] urls)
{
    var subTasks = from url in urls
                   let wc = new WebClient()
                   select wc.DownloadStringTaskAsync(url);

    return Task.WhenAll(subTasks); // Does not compile
}
Run Code Online (Sandbox Code Playgroud)

如何将生成的任务合并到字典中?

Jon*_*eet 15

您需要自己执行映射.例如,您可以使用:

static async Task<Dictionary<string,string>> GetUrls(string[] urls)
{
    var tasks = urls.Select(async url =>
    {
        using (var client = new WebClient())
        {
            return new { url, content = await client.DownloadStringTaskAsync(url) };
        };
    }).ToList();
    var results = await Task.WhenAll(tasks);
    return results.ToDictionary(pair => pair.url, pair => pair.content);
}
Run Code Online (Sandbox Code Playgroud)

请注意该方法必须如何async才能await在其中使用.

  • @SteveB:不 - `ToList()` 调用将返回一个 `List&lt;Task&lt;...&gt;&gt;`,其中所有任务都已并行*启动*。 (2认同)
  • @JonSkeet仍然在`HttpClient`,[官方文档](https://msdn.microsoft.com/en-us/library/system.net.http.httpclient(v = vs.110).aspx)列出了几种方法线程安全和[本文](http://blogs.msdn.com/b/henrikn/archive/2012/08/07/httpclient-httpclienthandler-and-httpwebrequesthandler.aspx)来自MSDN的Henrik Nielsen表示"单一HttpClient可用于同时发送任意数量的HTTP请求". (2认同)