4

I know that Task.Wait() block thread in which it is executed.

Do I understand correctly that Task.WaitAsync() does not do this?

I tried to find information about it but I didn't find anything

Theodor Zoulias
  • 34,835
  • 7
  • 69
  • 104

2 Answers2

8

WaitAsync will return a new task that needs to be awaited in turn. It's not used to avoid await, it's used to allow cancelling a wait for another task.

If you want you await for a task to complete without blocking you'll have to use await in an async method, or use ContinueWith with the continuation code:

async Task MyMethodAsync(Task myTask)
{
   ...
   await myTask;
   ...
}

This code can await forever and doesn't allow cancelling the wait. If you want to stop waiting after a while you can use Task.WaitAsync

...
try
{
    await myTask.WaitAsync(TimeSpan.FromMinute(1));
}
catch(TimeoutException)
{
    //Handle the timeout
}
...

Or you may want to cancel awaiting that task if a parent call signals cancellation through a CancellationTokenSource

async Task MyMethod(Task someTask,CancellationToken cancellationToken=default)
{
   ....
   await someTask.WaitAsync(cancellationToken);
   ...
}
Tore Nestenius
  • 16,431
  • 5
  • 30
  • 40
Panagiotis Kanavos
  • 120,703
  • 13
  • 188
  • 236
5

It is non-blocking since it returns a Task. See the documentation.

public Task WaitAsync(CancellationToken cancellationToken);
public Task WaitAsync(TimeSpan timeout);
public Task WaitAsync(TimeSpan timeout, CancellationToken cancellationToken);

Gets a Task that will complete when this Task completes, when the specified timeout expires, or when the specified CancellationToken has cancellation requested.

The implementation can be found here:

public static Task WaitAsync(this Task task, int millisecondsTimeout) =>
    WaitAsync(task, TimeSpan.FromMilliseconds(millisecondsTimeout), default);

public static Task WaitAsync(this Task task, TimeSpan timeout) =>
    WaitAsync(task, timeout, default);

public static Task WaitAsync(this Task task, CancellationToken cancellationToken) =>
    WaitAsync(task, Timeout.InfiniteTimeSpan, cancellationToken);

public async static Task WaitAsync(this Task task, TimeSpan timeout, CancellationToken cancellationToken)
{
    var tcs = new TaskCompletionSource<bool>();
    using (new Timer(s => ((TaskCompletionSource<bool>)s).TrySetException(new TimeoutException()), tcs, timeout, Timeout.InfiniteTimeSpan))
    using (cancellationToken.Register(s => ((TaskCompletionSource<bool>)s).TrySetCanceled(), tcs))
    {
        await(await Task.WhenAny(task, tcs.Task).ConfigureAwait(false)).ConfigureAwait(false);
    }
}
Theodor Zoulias
  • 34,835
  • 7
  • 69
  • 104
Peter Csala
  • 17,736
  • 16
  • 35
  • 75