任务取消抛出异常

时间:2015-04-21 15:11:30

标签: c# wpf task cancellationtokensource

所以,根据对this post的回答:

  

2)如果任务的主体也在监视取消令牌   并抛出一个包含该令牌的OperationCanceledException(其中   是什么ThrowIfCancellationRequested做的,然后当任务看到   在OCE中,它检查OCE的令牌是否与任务的令牌匹配。   如果是,则该异常被视为对此的确认   合作取消和任务过渡到已取消   国家(而不是Faulted州)。

由此我了解到,通过将令牌传递给任务的构造函数然后调用相同的令牌的ThrowIfCancellationRequested()方法,该任务实际上将安静地终止,而不必显式捕获OperationCanceledException。

然而事实证明,抛出异常,所以我相信我可能误解了这个机制。

我的代码:

  public void AI()
    {
        IsBusy = true;
        var token = stopGameCancellationTokenSource.Token;
        var workTask = new Task(() => aiWork(token), token);
        workTask.Start();
        workTask.ContinueWith(task => { IsBusy = false; });

    }

    private void aiWork(CancellationToken token)
    {

        while ( true)
        {

             //Some computation being done here

            token.ThrowIfCancellationRequested(); //Exception is thrown here, I thought it wouldn't

            //More computation here, which I don't want to happen if cancellation has benn requested
        }
    }

3 个答案:

答案 0 :(得分:3)

这一行

token.ThrowIfCancellationRequested();

显式抛出异常。链接告诉你的是,如果任务的令牌与刚刚抛出的OperationCanceledException中的令牌匹配,则#34;任务转换到已取消状态(而不是故障状态)。 #34;

所以最重要的是,如果您不想在取消任务时抛出异常,只需省略该行!

答案 1 :(得分:2)

除了为什么的@JurgenCamilleri answer中的解释,您收到了错误,您可能要做的是循环,直到请求取消。您可以通过将代码更改为以下内容来实现:

private void aiWork(CancellationToken token)
{
    while (!token.IsCancellationRequested)
    {
        //Some computation being done here

        if (token.IsCancellationRequested)
            break; // need to cancel

        //More computation here, which I don't want to happen if cancellation has been requested
    }
}    

答案 2 :(得分:1)

正如方法的名称所暗示的那样,ThrowIfCancellationRequested如果请求了胜利,则会抛出异常(OperationCanceledException)。

如果你真的不想抛出异常,你可以检查token.IsCancellationRequested是否为真,在这种情况下,退出你的函数。 但是,我建议坚持使用token.ThrowIfCancellationRequested(),除非你有充分的理由不这样做。