从Task.WhenAll获取返回值

20

希望这个问题相对简单。我有一组对象,每个对象都有一个异步方法,我想调用并收集其返回值。我想让它们并行运行。我想要实现的可以用一行错误的代码来概括:

IEnumerable<TestResult> results = await Task.WhenAll(myCollection.Select(v => v.TestAsync()));

我尝试了各种方法都没有成功,有任何想法吗?


1
TestAsync 是什么样子的? - i3arnon
2
这行代码看起来没问题。具体哪里出了问题?有编译器错误、运行时异常等吗? - Dennis
我猜他的 TestAsync() 签名看起来像这样:public async TestResult TestAsync(),而不是 public async Task<TestResult> TestAsync() - AlexMelw
有些相关:ForEachAsync with Result - Theodor Zoulias
2个回答

19

如果您正在等待的任务具有相同类型的结果,则Task.WhenAll将返回它们的数组。例如,对于这个类:

public class Test
{
    public async Task<TestResult> TestAsync()
    {
        await Task.Delay(1000); // Imagine an I/O operation.
        return new TestResult();
    }
}

我们得到了以下结果:

var myCollection = new List<Test>();
myCollection.Add(new Test());

IEnumerable<TestResult> results = await Task.WhenAll(myCollection.Select(v => v.TestAsync()));

4
这段代码与原作者编写的相同。最好澄清一下,他遇到了什么问题。 - Dennis
我已经解释了什么应该有效以及为什么。现在我在等待楼主澄清他有哪些问题。 - i3arnon
4
我是一个白痴——我的TestAsync方法返回的是一个任务(Task),而不是一个任务<TestResult>。当我改正后,它就可以工作了。感谢你指出正确的方向——即使错误就在我的眼前,我也看不到它! - wwarby
你能提供一个 TestAsync 接受参数且为 static 方法的示例吗? - Kraang Prime
对我有效的方法是在这个答案中将Task.WaitAll替换为await Task.WhenAll - gattsbr

3

像这样做:

public async Task RunMultipleTasksInParallelAsync()
{
    var tasks = new List<Task<MyResultType>>(); //<---- Add the return type here

    foreach (var item in items)
    {
        var task = DoSomethingAsync();
        tasks.Add(task);
    }

    var myResults = await Task.WhenAll(tasks);
}

public async Task<MyResultType> DoSomethingAsync()
{
    return new MyResultType();
}

认识到你需要将返回类型添加到任务列表中,否则 Task.WhenAll 将具有返回类型 "void"。

谢谢!那对我来说是缺失的拼图的一部分 - undefined

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