我现在一直在寻找解决方案,似乎必须是一个简单的问题。但是,我找到的每个示例都会创建一个与此类似的Task
集合(取自MSDN上的How to: Extend the Async Walkthrough by Using Task.WhenAll (C# and Visual Basic)页面):
IEnumerable<Task<int>> downloadTasksQuery =
from url in urlList select ProcessURLAsync(url);
我无法执行此操作,因为我想调用不同的async
方法和await
结果...更像是这样的东西(但不是这样,因为这似乎没有任何东西):
var getTicketTasks = new List<Task<IEnumerable<ITicket>>>();
getTicketTasks.Add(new Task(() => Model.GetTicketsAsync(eventDate)));
getTicketTasks.Add(new Task(() => Model.GetGuestTicketsAsync(eventDate)));
...
getTicketTasks.Add(new Task(() => Model.GetOtherTicketsAsync(eventDate)));
IEnumerable<ITicket>[] tickets = await Task.WhenAll(getTicketTasks);
那么如何使用Task.WhenAll
方法调用多个async
方法和await
结果?
答案 0 :(得分:7)
不要使用该任务构造函数来调用异步方法*。只需调用这些方法,将返回的任务和await
所有这些一起存储在Task.WhenAll
中:
var getTicketTasks = new List<Task<IEnumerable<ITicket>>>();
getTicketTasks.Add(Model.GetTicketsAsync(eventDate));
getTicketTasks.Add(Model.GetGuestTicketsAsync(eventDate));
...
getTicketTasks.Add(Model.GetOtherTicketsAsync(eventDate));
IEnumerable<ITicket>[] tickets = await Task.WhenAll(getTicketTasks);
在您的情况下,您创建了一个任务,但是您没有启动它,因此它不会运行。如果你确实启动它,你只需触发实际的异步操作而不将返回的任务存储在任何地方。这意味着你没有await
。您正在等待的所有任务都是开火并忘记了另一个async
操作。
Task.WhenAll
也有params
的重载,因此另一个选项是:
var tickets = await Task.WhenAll(
Model.GetTicketsAsync(eventDate),
Model.GetGuestTicketsAsync(eventDate),
Model.GetOtherTicketsAsync(eventDate));
*或在任何其他情况下。
答案 1 :(得分:2)
您刚刚创建了Task
。你从来没有开始过它。通过其构造函数创建Task
将不会启动Task
,因此也不会转换为已完成状态。所以等待它将需要永远。
使用Task.Run
或致电Task.Start
但不建议拨打Task.Start
。首选Task.Run
启动异步操作。如果您已经有Task<T>
,只需创建一个数组并等待它。
var getTicketTasks = new List<Task<IEnumerable<ITicket>>>();
getTicketTasks.Add(Model.GetTicketsAsync(eventDate));
getTicketTasks.Add(Model.GetGuestTicketsAsync(eventDate));
...
getTicketTasks.Add(Model.GetOtherTicketsAsync(eventDate));
IEnumerable<ITicket>[] tickets = await Task.WhenAll(getTicketTasks);