Reputation: 69985
I've been searching for a solution for a while now to what seems like it must be a simple problem. However, every example that I find creates a collection of Task
s similar to this one (taken from the How to: Extend the Async Walkthrough by Using Task.WhenAll (C# and Visual Basic) page on MSDN):
IEnumerable<Task<int>> downloadTasksQuery =
from url in urlList select ProcessURLAsync(url);
I am unable to do this as I want to call different async
methods and await
the results... something more like this (but not this because this doesn't seem to do anything):
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);
So how can I call a number of async
methods and await
the results using the Task.WhenAll
method?
Upvotes: 1
Views: 954
Reputation: 116676
Don't use that task constructor to call an asynchronous method*. Simply call these methods, store the returned tasks and await
all of them together with 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);
In your case you create a task, but you don't start it so it doesn't run. If you did start it you would simply fire your actual asynchronous operations without storing the returned task anywhere. That means that you have nothing to await
. All the tasks you are awaiting do is fire and forget another async
operation.
Task.WhenAll
also has an overload with params
so another option would be:
var tickets = await Task.WhenAll(
Model.GetTicketsAsync(eventDate),
Model.GetGuestTicketsAsync(eventDate),
Model.GetOtherTicketsAsync(eventDate));
* Or in any other case for that matter.
Upvotes: 7
Reputation: 73502
You've just created the Task
. You never started it. Creating a Task
via its constructor will not start the Task
and hence will not transform to completed state either. So awaiting it will take forever.
Use Task.Run
or call Task.Start
however calling Task.Start
isn't recommended. Prefer Task.Run
to start a asynchronous operation. If you already have Task<T>
simply create a array and await it.
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);
Upvotes: 2