fork download
  1. // OrtizOL - xCSw - http://o...content-available-to-author-only...t.com
  2.  
  3. using System;
  4. using System.Threading;
  5.  
  6. namespace Receta.CSharp.R0304
  7. {
  8. public class CancelacionOperacionAsincronica
  9. {
  10. public static void Main()
  11. {
  12. Console.WriteLine(Environment.NewLine);
  13.  
  14. // Primer enfoque: Comprobación de propiedad IsCancellationRequested:
  15. using (CancellationTokenSource cts = new CancellationTokenSource())
  16. {
  17. // Obtención de token para cancelación:
  18. CancellationToken token = cts.Token;
  19.  
  20. // Ejecución de operación asincrónica en pool de threads:
  21. ThreadPool.QueueUserWorkItem( _ => OperacionAsincronica1(token));
  22.  
  23. Thread.Sleep(TimeSpan.FromSeconds(2));
  24.  
  25. // Emite notificación de cancelación:
  26. cts.Cancel();
  27. }
  28.  
  29. // Segundo enfoque: Lanzamiento de excepción OperationCanceledException:
  30. using (CancellationTokenSource cts = new CancellationTokenSource())
  31. {
  32. CancellationToken token = cts.Token;
  33.  
  34. ThreadPool.QueueUserWorkItem( _ => OperacionAsincronica2(token));
  35.  
  36. Thread.Sleep(TimeSpan.FromSeconds(2));
  37.  
  38. // Emite notificación de cancelación para generación
  39. // de la excepción OperationCanceledException:
  40. cts.Cancel();
  41. }
  42.  
  43. // Tercer enfoque: Registro de callback para su invocación
  44. // cuando la operación sea cancelada:
  45. using (CancellationTokenSource cts = new CancellationTokenSource())
  46. {
  47. CancellationToken token = cts.Token;
  48.  
  49. ThreadPool.QueueUserWorkItem( _ => OperacionAsincronica3(token));
  50.  
  51. Thread.Sleep(TimeSpan.FromSeconds(2));
  52.  
  53. cts.Cancel();
  54. }
  55.  
  56. // Tiempo de espera adicional en Main:
  57. Thread.Sleep(TimeSpan.FromSeconds(2));
  58.  
  59. Console.WriteLine(Environment.NewLine);
  60. }
  61.  
  62. private static void OperacionAsincronica1(CancellationToken token)
  63. {
  64. Console.WriteLine ("Inicio operación asincrónica no. 1.");
  65.  
  66. for (int i = 1; i <= 5; ++i)
  67. {
  68. if (token.IsCancellationRequested)
  69. {
  70. Console.WriteLine ("La operación asincrónica no. 1 fue cancelada.");
  71. return;
  72. }
  73.  
  74. Thread.Sleep(TimeSpan.FromSeconds(1));
  75. }
  76.  
  77. Console.WriteLine ("La operación asincrónica no. 1 finalizó correctamente.");
  78. }
  79.  
  80. private static void OperacionAsincronica2(CancellationToken token)
  81. {
  82. try
  83. {
  84. Console.WriteLine ("Inicio operación asincrónica no. 2.");
  85.  
  86. for (int i = 1; i <= 5; ++i)
  87. {
  88. token.ThrowIfCancellationRequested();
  89. Thread.Sleep(TimeSpan.FromSeconds(1));
  90. }
  91.  
  92. Console.WriteLine ("La operación asincrónica no. 2 finalizó correctamente.");
  93. }
  94. catch(OperationCanceledException)
  95. {
  96. Console.WriteLine ("La operación asincrónica no. 2 ha sido cancelada.");
  97. }
  98. }
  99.  
  100. private static void OperacionAsincronica3(CancellationToken token)
  101. {
  102. bool centinelaCancelacion = false;
  103.  
  104. token.Register( () => centinelaCancelacion = true);
  105.  
  106. Console.WriteLine ("Inicio operación asincrónica no. 3.");
  107.  
  108. for(int i = 1; i <= 5; ++i)
  109. {
  110. if (centinelaCancelacion)
  111. {
  112. Console.WriteLine ("La operación asincrónica no. 3 ha sido cancelada.");
  113. return;
  114. }
  115. Thread.Sleep(TimeSpan.FromSeconds(1));
  116. }
  117.  
  118. Console.WriteLine ("La operación asincrónica no. 3 finalizó correctamente.");
  119. }
  120. }
  121. }
Success #stdin #stdout 0.05s 29672KB
stdin
Standard input is empty
stdout

Inicio operación asincrónica no. 1.
Inicio operación asincrónica no. 2.
La operación asincrónica no. 1 fue cancelada.
Inicio operación asincrónica no. 3.
La operación asincrónica no. 2 ha sido cancelada.
La operación asincrónica no. 3 ha sido cancelada.