与异步方法的任务关联起来的CancellationToken [英] Associate a CancellationToken with an async method's Task

查看:123
本文介绍了与异步方法的任务关联起来的CancellationToken的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问:有没有办法到的CancellationToken 与关联的工作返回从异步方法?

Question: Is there a way to associate a CancellationToken with the Task returned from an async method?

一般情况下,工作将在取消状态结束如果 OperationCancelledException 被抛出了的CancellationToken 匹配任务的的CancellationToken 。如果他们不匹配,则任务进入断陷状态:

Generally, a Task will end up in the Cancelled state if an OperationCancelledException is thrown with a CancellationToken matching the Task's CancellationToken. If they don't match, then the task goes into the Faulted state:

    void WrongCancellationTokenCausesFault()
    {
        var cts1 = new CancellationTokenSource();
        var cts2 = new CancellationTokenSource();
        cts2.Cancel();

        // This task will end up in the Faulted state due to the task's CancellationToken not matching the thrown 
        // OperationCanceledException's token.
        var task = Task.Run(() => cts2.Token.ThrowIfCancellationRequested(), cts1.Token);  
    }

使用异步 / 伺机,我还没有找到一种方法来设置方法的任务 的CancellationToken (从而达到相同的排序功能)。从我的测试,似乎的任何 OperationCancelledException 将导致异步方法进入取消状态:

With async/await, I haven't found a way to set the method's Task's CancellationToken (and thus achieve the same sort of functionality). From my testing, it seems that any OperationCancelledException will cause the async method to enter the Cancelled state:

    async Task AsyncMethodWithCancellation(CancellationToken ct)
    {
        // If ct is cancelled, this will cause the returned Task to be in the Cancelled state
        ct.ThrowIfCancellationRequested(); 
        await Task.Delay(1);

        // This will cause the returned Task to be in the Cancelled state
        var newCts = new CancellationTokenSource();
        newCts.Cancel();
        newCts.Token.ThrowIfCancellationRequested();
    }

这将是很好,有一点更多的控制权,因为如果我从我的调用一个方法异步方法被取消(我不希望取消 - 即它不是这个工作的CancellationToken ),我希望任务进入故障状态 - 而不是取消状态。

It would be nice to have a little more control, since if a method I call from my async method is cancelled (and I don't expect cancellation--i.e. its not this Task's CancellationToken), I would expect the task to enter the Faulted state--not the Cancelled state.

推荐答案

我认为设计非常适用于常见的情况:如果有孩子操作将被取消,则取消传播到父(最常见的情况是,父母和孩子共享取消标记)。

I think the design works well for the common case: if any child operations are cancelled, then the cancellation propagates to the parent (the most common case is that the parent and child share cancellation tokens).

如果你想要不同的语义,可以 OperationCanceledException 异步方法,并抛出一个适合您需要的语义异常。如果你想重复使用这些语义,对于一个扩展方法工作应符合要求。

If you want different semantics, you can catch the OperationCanceledException in your async method and throw an exception that fits the semantics you need. If you want to use these semantics repeatedly, an extension method for Task should fit the bill.

这篇关于与异步方法的任务关联起来的CancellationToken的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆