Как использовать свойство CancellationToken?
По сравнению с предыдущим кодом для classа RulyCanceler , я хотел запустить код с помощью CancellationTokenSource
.
Как использовать его, как указано в маркерах отмены , т. Е. Не бросать / ловить исключение? Можно ли использовать свойство IsCancellationRequested
?
Я попытался использовать его так:
- Синхронизированный блок Java против Collections.synchronizedMap
- Синхронизация и System.out.println
- Можно ли использовать мьютекс в многопроцессорном случае в Linux / UNIX?
- Заказ streamов для запуска в том порядке, в котором они были созданы / запущены
- Как @synchronized блокировка / разблокировка в Objective-C?
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(); } } } }
- В чем разница между синхронизацией на lockObject и использованием этого как блокировки?
- C # версия синхронизированного ключевого слова java?
- Убедитесь, что синхронизированные блокировки Java выполнены в порядке?
- Синхронизация IPC с общей памятью (без блокировки)
- Ожидание выполнения нескольких streamов в Java
- Java Singleton и синхронизация
- Как определить, заблокирован ли объект (синхронизирован), чтобы он не блокировался на Java?
- Чтение и запись C ++ int Atomic?
Вы можете реализовать свой метод работы следующим образом:
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/