fork(1) download
  1. // OrtizOL - xCSw - http://o...content-available-to-author-only...t.com
  2.  
  3. using System;
  4. using System.Collections.Generic;
  5. using System.Threading;
  6. using System.Threading.Tasks;
  7.  
  8. namespace Receta.CSharp.R0304
  9. {
  10. public class Medicion
  11. {
  12. public static void Main()
  13. {
  14. Console.WriteLine(Environment.NewLine);
  15.  
  16. // Creación de objeto CancellationTokenSource:
  17. CancellationTokenSource cts = new CancellationTokenSource();
  18. // Obtención de token de cancellación:
  19. CancellationToken token = cts.Token;
  20.  
  21. // Generador de números aleatorios:
  22. Random rnd = new Random();
  23. Object objLock = new Object();
  24.  
  25. // Creación de lista de tareas:
  26. List<Task<int[]>> tareas = new List<Task<int[]>>();
  27.  
  28. // Creación de objeto TaskFactory con token de cancellación:
  29. TaskFactory factory = new TaskFactory(token);
  30.  
  31. // Creación de cada una de las tareas:
  32. for (int tarea = 0; tarea <= 10; ++tarea)
  33. {
  34. int iteracion = tarea + 1;
  35.  
  36. // Agregación de tarea:
  37. tareas.Add(factory.StartNew( () => {
  38. int valor;
  39. int[] mediciones = new int[10];
  40.  
  41. for (int medicion = 1; medicion <= 10; ++medicion)
  42. {
  43. lock (objLock)
  44. {
  45. valor = rnd.Next(0, 101);
  46. }
  47. // Cancela el resto de mediciones cuando
  48. // la medicion es igual 0:
  49. if (valor == 0)
  50. {
  51. // Emite señal de cancelación:
  52. cts.Cancel();
  53. Console.WriteLine ("Cancelación de la tarea: {0}", iteracion);
  54. break;
  55. }
  56.  
  57. // Agrega la medición satisfactoria:
  58. mediciones[medicion - 1] = valor;
  59. }
  60.  
  61. return mediciones;
  62. }, token));
  63. }
  64.  
  65. try
  66. {
  67. // Se asegura que el promedio sea calculado una vez
  68. // todas las mediciones hayan sido satisfactorias:
  69. Task<double> resultadoPromedios = factory.ContinueWhenAll(tareas.ToArray(),
  70. (resultados) => {
  71. Console.WriteLine ("Calculando el promedio general...");
  72.  
  73. int suma = 0;
  74. int numMediciones = 0;
  75.  
  76. // Calculo del promedio por cada instrumento:
  77. foreach(var instrumento in resultados)
  78. {
  79. foreach(var medicion in instrumento.Result)
  80. {
  81. suma += medicion;
  82. ++numMediciones;
  83. }
  84. }
  85.  
  86. return suma / (double) numMediciones;
  87. }, token);
  88. Console.WriteLine ("El promedio es igual: {0:00}", resultadoPromedios.Result);
  89. }
  90. catch(AggregateException ae)
  91. {
  92. foreach(Exception e in ae.InnerExceptions)
  93. {
  94. if (e is TaskCanceledException)
  95. {
  96. Console.WriteLine ("No se pudo calcular el promedio.");
  97. }
  98. else
  99. {
  100. Console.WriteLine ("Excepción: {0}", e.GetType().Name);
  101. }
  102. }
  103. }
  104. finally
  105. {
  106. cts.Dispose();
  107. }
  108.  
  109. Console.WriteLine(Environment.NewLine);
  110. }
  111. }
  112. }
Success #stdin #stdout 0.08s 27744KB
stdin
Standard input is empty
stdout

Cancelación de la tarea: 6
No se pudo calcular el promedio.