// OrtizOL - xCSw - http://o...content-available-to-author-only...t.com using System; using System.Threading; namespace Receta.CSharp.R0304 { public class CancelacionOperacionAsincronica { public static void Main() { Console.WriteLine(Environment.NewLine); // Primer enfoque: Comprobación de propiedad IsCancellationRequested: using (CancellationTokenSource cts = new CancellationTokenSource()) { // Obtención de token para cancelación: CancellationToken token = cts.Token; // Ejecución de operación asincrónica en pool de threads: ThreadPool.QueueUserWorkItem( _ => OperacionAsincronica1(token)); Thread.Sleep(TimeSpan.FromSeconds(2)); // Emite notificación de cancelación: cts.Cancel(); } // Segundo enfoque: Lanzamiento de excepción OperationCanceledException: using (CancellationTokenSource cts = new CancellationTokenSource()) { CancellationToken token = cts.Token; ThreadPool.QueueUserWorkItem( _ => OperacionAsincronica2(token)); Thread.Sleep(TimeSpan.FromSeconds(2)); // Emite notificación de cancelación para generación // de la excepción OperationCanceledException: cts.Cancel(); } // Tercer enfoque: Registro de callback para su invocación // cuando la operación sea cancelada: using (CancellationTokenSource cts = new CancellationTokenSource()) { CancellationToken token = cts.Token; ThreadPool.QueueUserWorkItem( _ => OperacionAsincronica3(token)); Thread.Sleep(TimeSpan.FromSeconds(2)); cts.Cancel(); } // Tiempo de espera adicional en Main: Thread.Sleep(TimeSpan.FromSeconds(2)); Console.WriteLine(Environment.NewLine); } private static void OperacionAsincronica1(CancellationToken token) { Console.WriteLine ("Inicio operación asincrónica no. 1."); for (int i = 1; i <= 5; ++i) { if (token.IsCancellationRequested) { Console.WriteLine ("La operación asincrónica no. 1 fue cancelada."); return; } Thread.Sleep(TimeSpan.FromSeconds(1)); } Console.WriteLine ("La operación asincrónica no. 1 finalizó correctamente."); } private static void OperacionAsincronica2(CancellationToken token) { try { Console.WriteLine ("Inicio operación asincrónica no. 2."); for (int i = 1; i <= 5; ++i) { token.ThrowIfCancellationRequested(); Thread.Sleep(TimeSpan.FromSeconds(1)); } Console.WriteLine ("La operación asincrónica no. 2 finalizó correctamente."); } catch(OperationCanceledException) { Console.WriteLine ("La operación asincrónica no. 2 ha sido cancelada."); } } private static void OperacionAsincronica3(CancellationToken token) { bool centinelaCancelacion = false; token.Register( () => centinelaCancelacion = true); Console.WriteLine ("Inicio operación asincrónica no. 3."); for(int i = 1; i <= 5; ++i) { if (centinelaCancelacion) { Console.WriteLine ("La operación asincrónica no. 3 ha sido cancelada."); return; } Thread.Sleep(TimeSpan.FromSeconds(1)); } Console.WriteLine ("La operación asincrónica no. 3 finalizó correctamente."); } } }