2015-04-21 3 views
1

Таким образом, в соответствии с ответом на 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

Эта линия

token.ThrowIfCancellationRequested(); 

явно вызывает исключение. То, что говорила вам ссылка, заключается в том, что если токен задачи совпадает с токеном в только что выпущенном OperationCanceledException, «Задача переходит в состояние« Отменено »(а не в состояние« Сбой »)».

Итак, нижняя строка - это то, что вы не хотите, чтобы исключение было выбрано, когда задача была отменена, просто опустите эту строку!

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 
    } 
}  
1

Поскольку название метода предполагает, ThrowIfCancellationRequested сгенерирует исключение (OperationCanceledException), если cancelletion было предложено.

Если вы действительно не хотите, чтобы исключение было брошено, вы можете проверить, является ли значение token.IsCancellationRequested истинным, и в этом случае выйдите из своей функции. Однако я бы рекомендовал придерживаться token.ThrowIfCancellationRequested(), если у вас нет веских причин.