Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/elixir/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 将CancellationToken与异步方法关联';的任务_C#_Task Parallel Library_Async Await - Fatal编程技术网

C# 将CancellationToken与异步方法关联';的任务

C# 将CancellationToken与异步方法关联';的任务,c#,task-parallel-library,async-await,C#,Task Parallel Library,Async Await,问题:是否有方法将CancellationToken与从async方法返回的任务关联 通常,如果使用与任务的取消标记匹配的取消标记抛出操作取消异常,则任务将以取消状态结束。如果它们不匹配,则任务进入故障状态: void WrongCancellationTokenCausesFault() { var cts1 = new CancellationTokenSource(); var cts2 = new CancellationTokenSour

问题:是否有方法将
CancellationToken
与从
async
方法返回的
任务关联

通常,如果使用与
任务
取消标记
匹配的
取消标记抛出
操作取消异常
,则
任务
将以取消状态结束。如果它们不匹配,则任务进入故障状态:

    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);  
    }
使用
async
/
await
,我还没有找到一种方法来设置方法的
任务
取消令牌(从而实现相同的功能)。根据我的测试,似乎任何
操作取消异常
都会导致
异步
方法进入取消状态:

    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();
    }

如果有更多的控制,那就更好了,因为如果我从我的
异步
方法调用的方法被取消(我不希望取消——也就是说,它不是这个
任务
取消令牌
),我希望任务进入故障状态,而不是取消状态。

我认为该设计在常见情况下运行良好:如果取消了任何子操作,则取消会传播到父级(最常见的情况是父级和子级共享取消令牌)


如果需要不同的语义,可以在
async
方法中捕获
OperationCanceledException
,并抛出符合所需语义的异常。如果您想重复使用这些语义,那么
Task
的扩展方法应该符合要求。

。有点奇怪的是,子
任务
(非
异步
)最终可能会出现故障(由于
操作取消异常
具有错误的令牌),但这将导致父(
异步
)任务处于取消状态。大多数时候,我只是好奇和担心这个bug:一个意外的取消不会导致我的
async
代码失败,也许会延迟我注意到这个bug;e、 例如,如果您将已取消的令牌传递给
Task.Run
,则当
wait
ed时,您将获得引发
TaskCanceledException
的已取消任务,但如果您取消传递给
Task.Run
的令牌,则在任务启动后,您将获得引发
OperationCanceledException
(不是
TaskCanceledException
)当
wait
ed时。无论如何,你不必担心bug,因为你最终应该
wait
所有任务(你关心的),任何被取消的任务都会在
wait
ed时抛出
OperationCanceledException