Data hosted with ♥ by Pastebin.com - Download Raw - See Original
  1. using System;
  2. using System.Threading;
  3.  
  4. namespace Recetas.Cap04
  5. {
  6.     public class FibonacciMultithread
  7.     {
  8.         // Número de la serie fibonacci a calcular:
  9.         private long numero;
  10.         // Contiene el valor de la serie fibonacci calculado:
  11.         private long fibonacci;
  12.         // Notifica a los threads en espera que un evento ha ocurrido:
  13.         private ManualResetEvent calculoCompleto;
  14.        
  15.         public long Numero
  16.         {
  17.             get
  18.             {
  19.                 return numero;
  20.             }
  21.         }
  22.        
  23.         public long Fibonacci
  24.         {
  25.             get
  26.             {
  27.                 return numero;
  28.             }
  29.         }
  30.        
  31.         // Constructor:
  32.         public FibonacciMultithread(int numero, ManualResetEvent calculoCompleto)
  33.         {
  34.             this.numero = numero;
  35.             this.calculoCompleto = calculoCompleto;
  36.         }
  37.        
  38.         // Método que será encapsulado por el delegado WaitCallback:
  39.         public void ControlSegundoPlano(Object info)
  40.         {
  41.             // Mantiene el índice del thread que está ejecutando este método:
  42.             int indiceThread = (int) info;
  43.            
  44.             Console.WriteLine ("\tLa ejecución del hilo no. {0} ha empezado.", indiceThread);
  45.            
  46.             // Guarda el valor del calculo de la serie Fibonacci:
  47.             fibonacci = CalcularFibonacci(numero);
  48.            
  49.             Console.WriteLine ("\t\tLa ejecución del hilo no. {0} ha terminado.", indiceThread);
  50.            
  51.             // Indica que este hilo ha terminado su ejecución:
  52.             calculoCompleto.Set();
  53.         }
  54.        
  55.         // Versión recursiva del cálculo de la serie Fibonacci:
  56.         public long CalcularFibonacci (long num)
  57.         {
  58.             if (num <= 1)
  59.             {
  60.                 return num;
  61.             }
  62.             else
  63.             {
  64.                 return CalcularFibonacci(num -1) + CalcularFibonacci(num - 2);
  65.             }
  66.         }
  67.     }
  68.    
  69.     public sealed class UsoFibonacciMultithread
  70.     {
  71.         public static void Main()
  72.         {
  73.             // Número de series de Fibonacci a calcular:
  74.             const int seriesCalcular = 10;
  75.            
  76.             // Se utiliza una instancia de ManualResetEvent por cada
  77.             // instancia de `FibonacciMultithread` para controlar
  78.             // los eventos de finaliación:
  79.             ManualResetEvent[] calculoCompletos = new ManualResetEvent[seriesCalcular];
  80.            
  81.             // Instancias de `FibonacciMultithread` a calcular:
  82.             FibonacciMultithread[] fibonaccis = new FibonacciMultithread[seriesCalcular];
  83.            
  84.             // Cada instancia de `FibonacciMultithread` calculará
  85.             // un número de la serie:
  86.             Random aleatorio = new Random();
  87.            
  88.             // Preparación del pool de threads:
  89.             Console.WriteLine ("\nSe está iniciando la inicialización de {0} tareas...", seriesCalcular);
  90.             for (int i = 0; i < seriesCalcular; ++i)
  91.             {
  92.                 calculoCompletos[i] =  new ManualResetEvent(false);
  93.                 FibonacciMultithread fm = new FibonacciMultithread(aleatorio.Next(20, 40), calculoCompletos[i]);
  94.                
  95.                 fibonaccis[i] = fm;
  96.                
  97.                 // Tarea puesta en la cola de ejecución de threads:
  98.                 ThreadPool.QueueUserWorkItem(fm.ControlSegundoPlano, i);
  99.             }
  100.            
  101.             // Espera a que finaliza la ejecución de los threads del pool:
  102.             WaitHandle.WaitAll(calculoCompletos);
  103.             Console.WriteLine ("\nTodos los calculos de la serie fibonacci se han completado.");
  104.            
  105.             // Muestra los resultados de los cálculos:
  106.             for (int i = 0; i < fibonaccis.Length; ++i)
  107.             {
  108.                 Console.WriteLine ("\tFibonacci({0}) = {1}", fibonaccis[i].Numero.ToString(), fibonaccis[i].Fibonacci.ToString());
  109.             }
  110.            
  111.             Console.WriteLine     ();
  112.         }
  113.     }
  114. }