Task.WaitAsync 与 Task.Wait

Dan*_*ina 4 .net c# asynchronous task-parallel-library

我知道Task.Wait()执行它的块线程。

我的理解是否正确,Task.WaitAsync()不这样做?

我试图查找有关它的信息,但没有找到任何信息

Pan*_*vos 9

WaitAsync会返回一个需要依次等待的新任务。它不用于避免await,它用于允许取消等待另一个任务。

如果您希望等待任务完成而不阻塞,则必须awaitasync方法中使用,或ContinueWith与延续代码一起使用:

async Task MyMethodAsync(Task myTask)
{
   ...
   await myTask;
   ...
}
Run Code Online (Sandbox Code Playgroud)

此代码可以永远等待,并且不允许取消等待。如果您想在一段时间后停止等待,您可以使用Task.WaitAsync

...
try
{
    await myTask.WaitAsync(TimeSpan.FromMinute(1));
}
catch(TimeoutException)
{
    //Handle the timeout
}
...
Run Code Online (Sandbox Code Playgroud)

或者,如果父调用通过 a 发出取消信号,您可能希望取消等待该任务CancellationTokenSource

async Task MyMethod(Task someTask,CancellationToken cancellationToken=default)
{
   ....
   await someTask.WaitAsync(cancellationToken);
   ...
}
Run Code Online (Sandbox Code Playgroud)


Pet*_*ala 6

它是非阻塞的,因为它返回一个Task. 请参阅文档

public Task WaitAsync(CancellationToken cancellationToken);
public Task WaitAsync(TimeSpan timeout);
public Task WaitAsync(TimeSpan timeout, CancellationToken cancellationToken);
Run Code Online (Sandbox Code Playgroud)

获取Task当此操作完成Task、指定的超时到期或指定的CancellationToken取消请求时将完成的 。

可以在这里找到实现:

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);
    }
}
Run Code Online (Sandbox Code Playgroud)