I was watching a video called Becoming a C# Time Lord and at 0:35:36 this code popped up:
async Task<TResult[]> PurelyWhenAll<TResult> (params Task<TResult>[] tasks)
{
var killJoy = new TaskCompletionSource<TResult[]>();
foreach ( var task in tasks )
task.ContinueWith(ant =>
{
if ( ant.IsCanceled )
killJoy.TrySetCanceled();
else if ( ant.IsFaulted )
killJoy.TrySetException(ant.Exception.InnerException);
});
return await await Task.WhenAny(killJoy.Task, Task.WhenAll(tasks));
}
Does this mean that a task returns a task and because of that we have double await? If that is the case what happens concerning performance if we have more than two awaits? Is this good practice, should this be avoided?
Task.WhenAny
is going to return a Task<Task<TResult>>
:
Task.WhenAny()
will return the first task that completedTResult[]
.You might find it easy to understand with explanatory variables:
var firstCompletedTask = await Task.WhenAny(killJoy.Task, Task.WhenAll(tasks));
var firstResult = await firstCompletedTask;
return firstResult;
It's not clear why you're concerned around the performance of this - it's just two await expressions, not particularly different to any other method with two await expressions.
It's pretty natural to do this when using Task.WhenAny<TResult>(Task<TResult>[])
, given that the return type is a Task<Task<TResult>>
.
See more on this question at Stackoverflow