繁体   English   中英

如何使用ContinueWith处理任务取消?

[英]How to handle task cancellation using ContinueWith?

我有以下示例:

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获取取消令牌。 出于这个原因,我使用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的评论具体说明:

如果未满足通过continuationOptions参数指定的继续标准,则将取消继续任务而不是已安排。

由于您未满足为先行条件指定的标准(即,未取消),因此将取消延期。 您等待已取消的任务,因此导致DoAsync出现操作取消异常。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM