Data hosted with ♥ by Pastebin.com - Download Raw - See Original
  1. // OrtizOL - xCSw - http://ortizol.blogspot.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. }