// 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<Task<int[]>> tareas = new List<Task<int[]>>();
// 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<double> 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);
}
}
}