Как использовать свойство CancellationToken?

По сравнению с предыдущим кодом для classа RulyCanceler , я хотел запустить код с помощью CancellationTokenSource .

Как использовать его, как указано в маркерах отмены , т. Е. Не бросать / ловить исключение? Можно ли использовать свойство IsCancellationRequested ?

Я попытался использовать его так:

 cancelToken.ThrowIfCancellationRequested(); 

а также

 try { new Thread(() => Work(cancelSource.Token)).Start(); } catch (OperationCanceledException) { Console.WriteLine("Canceled!"); } 

но это дало ошибку времени выполнения для cancelToken.ThrowIfCancellationRequested(); в методе Work(CancellationToken cancelToken) :

 System.OperationCanceledException was unhandled Message=The operation was canceled. Source=mscorlib StackTrace: at System.Threading.CancellationToken.ThrowIfCancellationRequested() at _7CancellationTokens.Token.Work(CancellationToken cancelToken) in C:\xxx\Token.cs:line 33 at _7CancellationTokens.Token.c__DisplayClass1.b__0() in C:\xxx\Token.cs:line 22 at System.Threading.ThreadHelper.ThreadStart_Context(Object state) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) at System.Threading.ThreadHelper.ThreadStart() InnerException: 

Код, который я успешно выполнил, заставил OperationCanceledException в новом streamе:

 using System; using System.Threading; namespace _7CancellationTokens { internal class Token { private static void Main() { var cancelSource = new CancellationTokenSource(); new Thread(() => { try { Work(cancelSource.Token); //).Start(); } catch (OperationCanceledException) { Console.WriteLine("Canceled!"); } }).Start(); Thread.Sleep(1000); cancelSource.Cancel(); // Safely cancel worker. Console.ReadLine(); } private static void Work(CancellationToken cancelToken) { while (true) { Console.Write("345"); cancelToken.ThrowIfCancellationRequested(); } } } } 

Вы можете реализовать свой метод работы следующим образом:

 private static void Work(CancellationToken cancelToken) { while (true) { if(cancelToken.IsCancellationRequested) { return; } Console.Write("345"); } } 

Вот и все. Вам всегда нужно самостоятельно обрабатывать отмену – выйти из метода, когда наступает подходящее время для выхода (чтобы ваша работа и данные находились в состоянии согласованности)

UPDATE: Я предпочитаю не писать while (!cancelToken.IsCancellationRequested) потому что часто есть несколько точек выхода, где вы можете прекратить безопасное выполнение в цикле тела, и цикл обычно имеет некоторое логическое условие для выхода (перебирать все элементы в коллекции и т. Д.). Поэтому я считаю, что лучше не смешивать эти условия, поскольку они имеют разные намерения.

@ BrainSlugs83

Вы не должны слепо доверять всему, что было отправлено в stackoverflow. Комментарий в коде Йенса неверен, параметр не контролирует, выбрасываются ли исключения или нет.

MSDN очень ясно, что этот параметр контролирует, прочитал ли вы его? http://msdn.microsoft.com/en-us/library/dd321703(v=vs.110).aspx

Если throwOnFirstException истинно, исключение немедленно будет распространяться вне вызова Cancel, предотвращая обработку остальных обратных вызовов и отменяемых операций. Если throwOnFirstException является ложным, эта перегрузка будет агрегировать любые исключения, брошенные в исключение AggregateException, так что один обратный вызов, бросающий исключение, не будет препятствовать выполнению других зарегистрированных обратных вызовов.

Имя переменной также неверно, потому что Cancel вызывается в CancellationTokenSource, а не сам токен, а источник изменяет состояние каждого маркера, которым он управляет.

Вы можете использовать ThrowIfCancellationRequested без обработки исключения!

Использование ThrowIfCancellationRequested предназначено для использования из задачи (а не для streamа). При использовании в задании вам не нужно самостоятельно обрабатывать исключение (и получить ошибку Unhandled Exception). Это приведет к оставлению Задачи, и свойство Task.IsCancelled будет True. Обработка исключений не требуется.

В вашем конкретном случае измените Thread на задачу.

 try { var t = new Task(() => Work(cancelSource.Token)); t.Start(); } if (t.IsCancelled) Console.WriteLine("Canceled!"); } 

Вы можете создать задачу с маркером отмены, когда вы используете приложение goto background, вы можете отменить этот токен.

Вы можете сделать это в PCL https://developer.xamarin.com/guides/xamarin-forms/application-fundamentals/app-lifecycle

 var cancelToken = new CancellationTokenSource(); Task.Factory.StartNew(async () => { await Task.Delay(10000); // call web API }, cancelToken.Token); //this stops the Task: cancelToken.Cancel(false); 

Решением плеера является пользовательский таймер в Xamarin.Forms, секундомер, когда приложение goo background https://xamarinhelp.com/xamarin-forms-timer/

  • Статический и нестатический объект блокировки в синхронизированном блоке
  • Как сделать мой ArrayList streamобезопасным? Другой подход к проблеме в Java?
  • Синхронизация по целочисленному значению
  • Как сделать блокировку с несколькими чтениями / одиночной записью из более простых примитивов синхронизации?
  • Синхронный запрос в Node.js
  • Как работает блокировка?
  • Синхронизированный блок Java для .class
  • Монитор против Mutex в c #
  • В чем разница между атомными / летучими / синхронизированными?
  • Почему не логично синхронизировать логику?
  • Следует ли синхронизировать метод запуска? Почему или почему нет?
  • Давайте будем гением компьютера.