使用Task.WhenAny等待几个不同的异步操作的结果

She*_*dan 1 .net c# asynchronous task-parallel-library async-await

我一直在寻找一个解决方案,看起来它一定是一个简单的问题.但是,我找到的每个示例都创建了一个Task与此类似的集合(取自如何:使用MSDN上的Task.WhenAll(C#和Visual Basic)扩展异步演练):

IEnumerable<Task<int>> downloadTasksQuery = 
    from url in urlList select ProcessURLAsync(url);
Run Code Online (Sandbox Code Playgroud)

我无法做到这一点,因为我想调用不同的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);
Run Code Online (Sandbox Code Playgroud)

那么如何使用该方法调用多种async方法和await结果Task.WhenAll呢?

i3a*_*non 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);
Run Code Online (Sandbox Code Playgroud)

在您的情况下,您创建一个任务,但您没有启动它,因此它不会运行.如果你确实启动它,你只需触发实际的异步操作而不将返回的任务存储在任何地方.这意味着你什么都没有await.您正在等待的所有任务都是开火并忘记了另一项async操作.

Task.WhenAll还有一个重载,params所以另一种选择是:

var tickets = await Task.WhenAll(
    Model.GetTicketsAsync(eventDate),
    Model.GetGuestTicketsAsync(eventDate),
    Model.GetOtherTicketsAsync(eventDate));
Run Code Online (Sandbox Code Playgroud)

*或在任何其他情况下.