using System;
using System.Threading;
namespace Recetas.Cap04
{
public class FibonacciMultithread
{
// Número de la serie fibonacci a calcular:
private long numero;
// Contiene el valor de la serie fibonacci calculado:
private long fibonacci;
// Notifica a los threads en espera que un evento ha ocurrido:
private ManualResetEvent calculoCompleto;
public long Numero
{
get
{
return numero;
}
}
public long Fibonacci
{
get
{
return numero;
}
}
// Constructor:
public FibonacciMultithread(int numero, ManualResetEvent calculoCompleto)
{
this.numero = numero;
this.calculoCompleto = calculoCompleto;
}
// Método que será encapsulado por el delegado WaitCallback:
public void ControlSegundoPlano(Object info)
{
// Mantiene el índice del thread que está ejecutando este método:
int indiceThread = (int) info;
Console.WriteLine ("\tLa ejecución del hilo no. {0} ha empezado.", indiceThread);
// Guarda el valor del calculo de la serie Fibonacci:
fibonacci = CalcularFibonacci(numero);
Console.WriteLine ("\t\tLa ejecución del hilo no. {0} ha terminado.", indiceThread);
// Indica que este hilo ha terminado su ejecución:
calculoCompleto.Set();
}
// Versión recursiva del cálculo de la serie Fibonacci:
public long CalcularFibonacci (long num)
{
if (num <= 1)
{
return num;
}
else
{
return CalcularFibonacci(num -1) + CalcularFibonacci(num - 2);
}
}
}
public sealed class UsoFibonacciMultithread
{
public static void Main()
{
// Número de series de Fibonacci a calcular:
const int seriesCalcular = 10;
// Se utiliza una instancia de ManualResetEvent por cada
// instancia de `FibonacciMultithread` para controlar
// los eventos de finaliación:
ManualResetEvent[] calculoCompletos = new ManualResetEvent[seriesCalcular];
// Instancias de `FibonacciMultithread` a calcular:
FibonacciMultithread[] fibonaccis = new FibonacciMultithread[seriesCalcular];
// Cada instancia de `FibonacciMultithread` calculará
// un número de la serie:
Random aleatorio = new Random();
// Preparación del pool de threads:
Console.WriteLine ("\nSe está iniciando la inicialización de {0} tareas...", seriesCalcular);
for (int i = 0; i < seriesCalcular; ++i)
{
calculoCompletos[i] = new ManualResetEvent(false);
FibonacciMultithread fm = new FibonacciMultithread(aleatorio.Next(20, 40), calculoCompletos[i]);
fibonaccis[i] = fm;
// Tarea puesta en la cola de ejecución de threads:
ThreadPool.QueueUserWorkItem(fm.ControlSegundoPlano, i);
}
// Espera a que finaliza la ejecución de los threads del pool:
WaitHandle.WaitAll(calculoCompletos);
Console.WriteLine ("\nTodos los calculos de la serie fibonacci se han completado.");
// Muestra los resultados de los cálculos:
for (int i = 0; i < fibonaccis.Length; ++i)
{
Console.WriteLine ("\tFibonacci({0}) = {1}", fibonaccis[i].Numero.ToString(), fibonaccis[i].Fibonacci.ToString());
}
Console.WriteLine ();
}
}
}