1

因此,根据对这篇文章的回答:

2) 如果任务主体也在监视取消令牌并抛出包含该令牌的 OperationCanceledException(这是 ThrowIfCancellationRequested 所做的),那么当任务看到该 OCE 时,它会检查 OCE 的令牌是否与任务的令牌匹配。如果是这样,则该异常被视为对合作取消的确认,并且任务转换到 Canceled 状态(而不是 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
        }
    }
4

3 回答 3

3

这条线

token.ThrowIfCancellationRequested();

显式抛出异常。该链接告诉您的是,如果任务的令牌与OperationCanceledException刚刚抛出的令牌匹配,“任务将转换为 Canceled 状态(而不是 Faulted 状态)。”

所以底线是,如果您不希望在取消任务时引发异常,只需省略该行!

于 2015-04-21T15:19:48.090 回答
2

In addition to the explanation in @JurgenCamilleri answer of why you are getting the error, what you likely intended to do was loop until cancellation was requested. You can do that by changing your code to something like this:

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
    }
}    
于 2015-04-21T15:31:36.497 回答
1

As the name of the method suggests, ThrowIfCancellationRequested will throw an exception (OperationCanceledException) if a cancelletion was requested.

If you really don't want an exception to be thrown, you can check if token.IsCancellationRequested is true and, in this case, exit your function. However, I'd recommand sticking with token.ThrowIfCancellationRequested() unless you got good reasons not to.

于 2015-04-21T15:32:29.290 回答