Det*_*ras 1 c# task-parallel-library async-await .net-5
因此,我在使用第三方库时遇到了问题,即使调用cancellationToken.Cancel. 下面是一个原型,可以解决这种情况并且它可以工作。
public async Task MainAsync()
{
try
{
await StartAsync().ConfigureAwait(false);
}
catch (Exception ex)
{
Console.WriteLine("Exception thrown");
}
}
private async Task<string> StartAsync()
{
var cts = new CancellationTokenSource();
cts.CancelAfter(3 * 1000);
var tcs = new TaskCompletionSource<string>();
cts.Token.Register(() => { Console.WriteLine("Cancelled"); tcs.TrySetCanceled(); });
return await (await Task.WhenAny(tcs.Task, LongComputationAsync())
.ConfigureAwait(false)).ConfigureAwait(false);
}
private async Task<string> LongComputationAsync()
{
await Task.Delay(1 * 60 * 1000).ConfigureAwait(false);
return "Done";
}
Run Code Online (Sandbox Code Playgroud)
所以上面的代码会等待 3 秒,然后它会抛出一个TaskCancelledException应该的异常。如果您随后将方法更改LongComputationAsync为以下内容:
private Task<string> LongComputationAsync()
{
Task.Delay(1 * 60 * 1000).ConfigureAwait(false).GetAwaiter().GetResult();
return Task.FromResult("Done");
}
Run Code Online (Sandbox Code Playgroud)
我仍然希望它具有相同的行为,但它的作用是,它将等待整整 1 分钟(在 中指定LongComputationAsync()),然后抛出TaskCancelledException.
谁能向我解释一下吗?关于这是如何运作的,或者这是否是正确的行为。
谁能向我解释一下吗?
当然。问题与 没有任何关系WhenAny。相反,问题在于代码假定方法是同步的,但它是异步的。
这是一个相对容易犯的错误。但作为一般规则,具有异步签名的方法可能是异步的;它不必是异步的。
正如我在博客中所描述的,异步方法开始同步执行,就像同步方法一样。只有当它们命中时,await它们才可以异步运行(即使如此,它们也可以同步继续)。
因此,新版本的LongCompuationAsync是同步的,它在将任务返回到 之前执行整个方法StartAsync,然后将任务传递给WhenAny。
| 归档时间: |
|
| 查看次数: |
119 次 |
| 最近记录: |