Должен ли я использовать IsCancellationRequested из токена или источника, когда оба доступны? - PullRequest
10 голосов
/ 06 мая 2011

Если у меня есть CancellationTokenSource, который все еще находится в области действия при проверке отмены - например, если я только что сделал запрос к базе данных и еще не передал CancellationToken в Задачи для обработки результатов - следуетЯ получаю доступ к IsCancellationRequested из источника или из его токена?

Другими словами, если оба варианта доступны, что является предпочтительным и почему?

1:

myCancellationTokenSource.IsCancellationRequested

2:

myCancellationTokenSource.Token.IsCancellationRequested

Ответы [ 3 ]

6 голосов
/ 06 мая 2011

В этом конкретном сценарии, я считаю, что эти два по существу эквивалентны. Я бы предпочел использовать токен хотя бы потому, что это упрощает рефакторинг, если позже вы отделите логическую проверку отмены от логики, создающей источник отмены. Для этого я бы сохранил токен в локальной ссылке и использовал эту ссылку для проверки.

1 голос
/ 06 мая 2011

Я бы использовал токен, хотя по крайней мере для варианта 1 эффект, вероятно, тот же. CancellationTokens - это типы значений только для чтения, которые предназначены для передачи по клиентскому коду, а CancellationTokenSource - это IDisposable с некоторыми внутренними ресурсами ... В целях безопасности я бы предпочел использовать его следующим образом:

void MethodA() {
 // Context in which CancellationTokenSource is known
 using (var tSource = new CancellationTokenSource()) {
  ThreadPool.QueueWorkItem( pArg => MethodB(tSource.Token) );
  ThreadPool.QueueWorkItem( pArg => MethodC(tSource.Token) );
  // ...

  // some other work to do

  // cancel
  if (mSomethingHappend) {
   tSource.Cancel();
  }
 }
}

private static void MethodB( CancellationToken pToken )
{
 // ...
}
1 голос
/ 06 мая 2011

Обычно myCancellationTokenSource используется для запуска отмены (например, родительским потоком). myCancellationTokenSource.Token является ассоциированным CancellationToken, который вы передадите в нечто вроде TaskFactory.StartNew(). Затем задание будет отслеживать CancellationToken.IsCancellationRequested, чтобы определить, когда завершить работу.

...