【问题标题】:How to run mutliple tasks at once and add return values to a list?如何一次运行多个任务并将返回值添加到列表中?
【发布时间】:2022-01-05 05:01:00
【问题描述】:

一次运行多个tasks 并将它们的返回值添加到c 语言列表中的最简单方法是什么? 我尝试了几种方法,但我可能做错了一切,因此我没有太多代码可以在这里发布。

更新:

这是我的失败尝试之一。我基本上是在尝试从链接中获取 JSON 字典(每个任务的链接都不同),然后将所有 JSON 字典添加到最后的单个列表中。但我希望所有任务同时运行。

static class Program
{
    static void Main()
    {
        List<dynamic> writeList = new List<dynamic>();
        for (int i = 0; i <= 50; i++)
        {
            Task<dynamic> task = Task<dynamic>.Factory.StartNew(
                () => savePageData("www.someJsonlink.com"));
            writeList.Add(task);
        }
    }

    static dynamic savePageData(string url)
    {
        WebClient client = new WebClient();
        string page = client.DownloadString(url);
        var data = JsonConvert.DeserializeObject(page);
        return data;

    }
}

这种方法的问题是没有任何东西被添加到列表中。实际上也没有连接到链接。但是如果正常完成,数据是存在的。

【问题讨论】:

  • 附带说明,而不是Task&lt;dynamic&gt;.Factory.StartNew 更可取:Task.Run。你可以阅读这两种方法的区别here

标签: c# task task-parallel-library taskfactory


【解决方案1】:

最简单的方法可能是使用Select LINQ 运算符,结合Task.WhenAll 方法:

int[] ids = GetIds();
Task<Image>[] tasks = ids.Select(id => DownloadImageAsync(id)).ToArray();
Image[] results = await Task.WhenAll(tasks);

在此示例中,Select 运算符将每个int 投影到Task&lt;Image&gt;,从而产生IEnumerable&lt;Image&gt; 序列。使用ToArray LINQ 运算符将此序列具体化为Task&lt;Image&gt; 数组。

如果您为每个图像调用的方法不是异步的,那么您可以这样做而不是.Select(id =&gt; DownloadImageAsync(id)).Select(id =&gt; Task.Run(() =&gt; DownloadImage(id)))。这样,将使用ThreadPool 线程并行调用多个DownloadImage。池中的线程数量是有限的,因此您很可能无法获得与真正异步的 DownloadImageAsync 调用所获得的相同程度的并行度。

【讨论】:

  • 您能详细说明一下第 2 行和第 3 行吗?我的理解是我们得到一个int 的列表,然后在第 2 行我们使用该列表中的每个值来创建一个任务(任务数将对应于ids.Count?)最后在第 3 行我们收集所有返回值并在所有任务完成后将它们放在一个列表中。我说的对吗?
  • 如果您不介意再看一遍,我也更新了这个问题。
  • @Mahdi_J 是的,这正是这段代码 sn-p 所做的。最终结果的数量和顺序与原始 id 相同。
  • 谢谢。你能想到另一种更接近我的方法吗(我更新了问题)?因为我对 c# 不是很熟悉,而且像你的方法一样简单,坦率地说,我很难理解它。
  • @Mahdi_J 在您自己的示例中,您只需在Main 方法的末尾添加这一行:var results = Task.WhenAll(writeList).Result;resultsdynamic 对象的数组。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-08
  • 2016-04-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多