Reputation: 6692
I want to make sure that I am using ContinueWhenAll appropriately. I have a number of calls which will run asynch and then I want to complete to a final task only after the other tasks have completed successfully and after I do some calcs on the results to see if I should instead stop processing and return a forbidden HTTP result. What I am unsure about is whether the final line will actually wait for all the other tasks to complete, or whether I need to structure it differently. If so, how should the last line be structured so that it is called ONLY if I get past the evaluation of if(getPlatformTask.Result...
// run some tasks and then gather them here
Task.Factory.ContinueWhenAll(new Task[]{ getPlatformTask, getUserTask },
(tasks) =>
{
Task.WaitAll(tasks);
if (getPlatformTask.Result == null || getUserTask.Result == null)
{
return Task<HttpResponseMessage>.Factory.StartNew(() =>
{
return new HttpResponseMessage(HttpStatusCode.Forbidden);
});
}
});
// will this line below get called before the inner task above completes?
return base.SendAsync(request, cancellationToken);
Upvotes: 2
Views: 1595
Reputation: 244827
If you want to block the current thread until all the tasks complete, you can simply use Task.WaitAll()
, no need to use continuation tasks. But keep in mind that blocked thread is a thread that does nothing but use up resources (like memory). Blocking a thread is often easier, but less efficient way to do things.
The code might look like this:
// run the tasks
Task.WaitAll(getPlatformTask, getUserTask);
// process the results
return base.SendAsync(request, cancellationToken);
And no, in your version, the last line can (and most likely will) execute before all the tasks are complete. ContinueWhenAll()
does not block, that's the whole point of it.
EDIT: I just realized that your method returns a Task
. So you actually don't have to block the thread, you can instead return a Task
that is completed when all the work is done. It could look like this:
// run the tasks
var result = Task.Factory.ContinueWhenAll(
new[] { getPlatformTask, getUserTask },
_ =>
{
// process the results
return base.SendAsync(request, cancellationToken);
});
return result.Unwrap();
Here, result
is Task<Task<HttpResponseMessage>>
, but you need just Task<HttpResponseMessage>
. To do that, you can use the Unwrap()
method.
Upvotes: 3