我有以下示例:
public void Run()
{
var ctc = new CancellationTokenSource();
try
{
DoAsync(ctc).Wait();
Console.WriteLine("Done");
}
catch (AggregateException exception)
{
Console.WriteLine("Inside try-catch block");
Console.WriteLine();
Console.WriteLine(exception);
exception.Handle(ex =>
{
Console.WriteLine(ex.Message);
return true;
});
}
}
private async Task DoAsync(CancellationTokenSource ctc)
{
Console.WriteLine("DoAsync started");
await Task.Run(() =>
Console.WriteLine("DoAsync Run"),
ctc.Token
)
.ContinueWith(antecedent =>
Console.WriteLine("DoAsync Run cancelled"),
TaskContinuationOptions.OnlyOnCanceled
);
Console.WriteLine("DoAsync finished");
}
我创建了一个方法 (DoAsync),它执行一些异步工作并且可以随时取消。
如您所见,Task.Run 获得了一个取消 token 。为此,我使用 continuationOptions = TaskContinuationOptions.OnlyOnCanceled 创建了延续任务。
因此,我预计只有在请求取消时才会调用延续任务,而在其他情况下 - 将被忽略。
但是在我的实现中,ContinueWith 返回的任务在其先行任务未被取消时抛出异常:
DoAsync started
DoAsync Run
Inside try-catch block
System.AggregateException...
A task was canceled.
我可以通过添加另一个 ContinueWith 来解决这个问题,如下例所示:
await Task.Run(() =>
Console.WriteLine("DoAsync Run"),
ctc.Token
)
.ContinueWith(antecedent =>
Console.WriteLine("DoAsync Run cancelled"),
TaskContinuationOptions.OnlyOnCanceled
)
.ContinueWith(antecedent => { });
并且这段代码不会抛出任何异常。
但是我可以使用单个 ContinueWith 正确处理取消吗?
最佳答案
ContinueWith
的注释具体说明:
If the continuation criteria specified through the continuationOptions parameter are not met, the continuation task will be canceled instead of scheduled.
由于未满足您为前提指定的条件(即未取消),因此将继续设置为取消。您等待取消的任务,因此导致 DoAsync
出现操作取消异常错误。
关于c# - 如何使用 ContinueWith 处理任务取消?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46055011/