// OrtizOL - xCSw - http://o...content-available-to-author-only...t.com using System; using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; namespace Receta.CSharp.R0304 { public class Medicion { public static void Main() { Console.WriteLine(Environment.NewLine); // Creación de objeto CancellationTokenSource: CancellationTokenSource cts = new CancellationTokenSource(); // Obtención de token de cancellación: CancellationToken token = cts.Token; // Generador de números aleatorios: Random rnd = new Random(); Object objLock = new Object(); // Creación de lista de tareas: List> tareas = new List>(); // Creación de objeto TaskFactory con token de cancellación: TaskFactory factory = new TaskFactory(token); // Creación de cada una de las tareas: for (int tarea = 0; tarea <= 10; ++tarea) { int iteracion = tarea + 1; // Agregación de tarea: tareas.Add(factory.StartNew( () => { int valor; int[] mediciones = new int[10]; for (int medicion = 1; medicion <= 10; ++medicion) { lock (objLock) { valor = rnd.Next(0, 101); } // Cancela el resto de mediciones cuando // la medicion es igual 0: if (valor == 0) { // Emite señal de cancelación: cts.Cancel(); Console.WriteLine ("Cancelación de la tarea: {0}", iteracion); break; } // Agrega la medición satisfactoria: mediciones[medicion - 1] = valor; } return mediciones; }, token)); } try { // Se asegura que el promedio sea calculado una vez // todas las mediciones hayan sido satisfactorias: Task resultadoPromedios = factory.ContinueWhenAll(tareas.ToArray(), (resultados) => { Console.WriteLine ("Calculando el promedio general..."); int suma = 0; int numMediciones = 0; // Calculo del promedio por cada instrumento: foreach(var instrumento in resultados) { foreach(var medicion in instrumento.Result) { suma += medicion; ++numMediciones; } } return suma / (double) numMediciones; }, token); Console.WriteLine ("El promedio es igual: {0:00}", resultadoPromedios.Result); } catch(AggregateException ae) { foreach(Exception e in ae.InnerExceptions) { if (e is TaskCanceledException) { Console.WriteLine ("No se pudo calcular el promedio."); } else { Console.WriteLine ("Excepción: {0}", e.GetType().Name); } } } finally { cts.Dispose(); } Console.WriteLine(Environment.NewLine); } } }