6

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

1
  • Task.WaitAsync() is useful when you want to make a Task cancellable based on a timeout and executes without blocking. Commented Nov 3, 2023 at 8:48

2 Answers 2

14

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); ... } 
Sign up to request clarification or add additional context in comments.

Comments

6

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); } } 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.