使用Task.WaitAll()时如何获取任务的返回值

7

我需要并行执行多个 Task<List<string>> 并将它们合并成一个新的 List<string>,然后获取返回值。

这是我目前的代码。从fiddle中可以看到,任务是并行执行的(执行时间约为1秒)。问题是我不知道如何获取每次执行的返回值(一个List<string>对象),以便我可以将它们合并。

Fiddle: https://dotnetfiddle.net/91YqkY

代码:

using System;
using System.Threading;
using System.Threading.Tasks;
using System.Collections.Generic;

public class Program
{
    public static void Main()
    {
        var filters = new List<string>
        {
            "A", "B", "C"
        }

        ;
        var api = new API();
        var TaskList = new List<Task>();
        foreach (var f in filters)
        {
            var LastTask = new Task<List<String>>(() =>
            {
                return api.GetArray(f);
            }

            );
            LastTask.Start();
            TaskList.Add(LastTask);
        }

        Task.WaitAll(TaskList.ToArray());
        foreach (var t in TaskList)
        {
            // I need to get the List<string> returned in each GetArray and merge them
        }
    }
}

public class API
{
    public List<string> GetArray(string param)
    {
        Thread.Sleep(1000);
        return new List<String>{
            param + "1",
            param + "2",
            param + "3",
        };
    }
}

我不想显得过于苛刻,但是Task并不是“并行执行”的,对吧?它们是异步执行的。此外,您可以根据完成顺序采取行动,或者基于另一个任务的完成继续执行。 - Eric Lease
你说得对,但是自从我开始一个任务后,我接下来要做的就是开始下一个任务,依此类推。我可以说它们是并行执行的,因为总执行时间是1秒,每个任务需要1秒完成。 - empz
1个回答

7
您可以尝试使用SelectMany方法:
var result = TaskList.Select(t => t.Result)
                     .SelectMany(r => r)
                     .ToList();

最初,您将TaskList的每个元素投射到其结果中,该对象是一个TaskList<string>对象,然后使用SelectMany方法定义所有任务结果中的字符串序列。 最后但并非最不重要的,您必须调用ToList,以便执行查询并获得List<string>作为结果。

更新

正如Sergey在下面的评论中正确指出的那样,您需要重新定义TaskList

var TaskList = new List<Task<List<string>>();

1
在这种情况下,所有任务都返回一个 Task<List<string>>。这样的 Task 对象的 Result 属性是一个 List<string>。一般来说,Task<T>Result 属性是一个 T 对象。 - Christos
3
@emzero,请使用以下本地变量的定义:var TaskList = new List<Task<List<String>>>(); - Sergey Vyacheslavovich Brunov
1
哦,你说得对。我漏掉了那个。谢谢! - empz
2
@SergeyBrunov 很好的发现 :) 我会把它加到我的答案中。 - Christos
1
@emzero,这没什么。 - Sergey Vyacheslavovich Brunov
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接