with run how cancellationtoken cancel c# multithreading asynchronous concurrency synchronization

c# - run - ¿Cómo usar la propiedad CancellationToken?



cancellationtokensource (4)

Comparado con el código anterior para la clase RulyCanceler , quería ejecutar código usando CancellationTokenSource .

¿Cómo lo uso como se menciona en los tokens de cancelación , es decir, sin arrojar / atrapar una excepción? ¿Puedo usar la propiedad IsCancellationRequested ?

Intenté usarlo así:

cancelToken.ThrowIfCancellationRequested();

y

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

pero esto dio un error de tiempo de cancelToken.ThrowIfCancellationRequested(); en cancelToken.ThrowIfCancellationRequested(); en el método 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.<Main>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:

El código que ejecuté exitosamente capturó la OperationCanceledException en el nuevo hilo:

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(); } } } }


¡PUEDE usar ThrowIfCancellationRequested sin manejar la excepción!

El uso de ThrowIfCancellationRequested está destinado a ser utilizado desde dentro de una tarea (no un subproceso). Cuando se usa dentro de una Tarea, no tiene que manejar la excepción usted mismo (y obtener el error de Excepción no controlada). Conseguirá abandonar la Tarea y la propiedad Task.IsCancelled será True. No se requiere manejo de excepciones.

En su caso específico, cambie el hilo a una tarea.

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


@ BrainSlugs83

No deberías confiar ciegamente en todo lo publicado en . El comentario en el código de Jens es incorrecto, el parámetro no controla si se lanzan o no excepciones.

MSDN tiene muy claro qué controla ese parámetro, ¿lo has leído? http://msdn.microsoft.com/en-us/library/dd321703(v=vs.110).aspx

Si throwOnFirstException es verdadero, una excepción se propagará inmediatamente fuera de la llamada a Cancelar, evitando que se procesen las devoluciones de llamadas restantes y las operaciones cancelables. Si throwOnFirstException es falso, esta sobrecarga agregará cualquier excepción lanzada en una AggregateException, de modo que una devolución de llamada que arroje una excepción no evitará que se ejecuten otras devoluciones de llamada registradas.

El nombre de la variable también es incorrecto porque se llama a Cancel en CancellationTokenSource, no el token en sí mismo y el origen cambia el estado de cada token que administra.


Puede crear una Tarea con token de cancelación, cuando la aplicación Goto Background puede cancelar este token.

Puede hacerlo en 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);

La solución de Anther es el temporizador de usuario en Xamarin.Forms, detener el temporizador cuando la aplicación goto background https://xamarinhelp.com/xamarin-forms-timer/


Puede implementar su método de trabajo de la siguiente manera:

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

Eso es. Siempre debe manejar la cancelación usted mismo: salga del método cuando sea el momento apropiado para salir (para que su trabajo y sus datos estén en estado constante)

ACTUALIZACIÓN: Prefiero no escribir while (!cancelToken.IsCancellationRequested) porque a menudo hay pocos puntos de salida donde puede detener la ejecución segura en el cuerpo del bucle, y el bucle suele tener alguna condición lógica para salir (iterar sobre todos los elementos en la colección, etc.). Entonces creo que es mejor no mezclar esas condiciones ya que tienen diferentes intenciones.