Advertisement
Fhernd

TecnicasInvocacionAsincronica.cs

Sep 16th, 2014
635
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 9.43 KB | None | 0 0
  1. using System;
  2. using System.Threading;
  3. using System.Collections;
  4.  
  5. namespace Recetas.Cap04
  6. {
  7.     public sealed class TecnicasInvocacionAsincronica
  8.     {
  9.         // Método utilitario para la presentación de datos
  10.         // de ejecución de los métodos con ejecución asincrónica:
  11.         private static void VisorDatos(DateTime hora, string mensaje)
  12.         {
  13.             Console.WriteLine ("[{0,3}/{1}] - {2} : {3}", Thread.CurrentThread.ManagedThreadId,
  14.                                Thread.CurrentThread.IsThreadPoolThread ? "pool" : "principal",
  15.                                hora.ToString ("HH:mm:ss.ffff"), mensaje);
  16.         }
  17.        
  18.         // Delegado para permitir la ejecución de métodos
  19.         // con la firma compatible:
  20.         public delegate DateTime AsyncMetodosDelegate(int retraso, string nombre);
  21.        
  22.         // Método que simula la ejecución de una tarea que toma
  23.         // varios segundos:
  24.         public static DateTime ProcesoLargo (int retraso, string nombre)
  25.         {
  26.             VisorDatos (DateTime.Now, String.Format ("{0} - thread en ejecución."));
  27.            
  28.             // Simula la ejecución de tareas que toman tiempo:
  29.             Thread.Sleep (retraso);
  30.            
  31.             VisorDatos (DateTime.Now, String.Format ("{0} - thread finalizado."));
  32.            
  33.             return DateTime.Now;
  34.         }
  35.        
  36.         // Aplicación del patrón (técnica) de determinación de completidud
  37.         // de invocación asincrónica `Blocking`:
  38.         public static void Blocking()
  39.         {
  40.             Console.WriteLine ("\n === Aplicación Técnica Blocking === ");
  41.            
  42.             // Creación y encapsulamiento con delegado:
  43.             AsyncMetodosDelegate procesoLargo = ProcesoLargo;
  44.            
  45.             // Inicia la invocación asincrónica:
  46.             IAsyncResult asyncResult = procesoLargo.BeginInvoke (2000, "Blocking", null, null);
  47.            
  48.             // Antes de que se realice el bloqueo se ejecutan estas instrucciones:
  49.             for (int i = 0; i < 3; ++i)
  50.             {
  51.                 VisorDatos (DateTime.Now, "Continua ejecutándose antes de bloquearse...");
  52.                 Thread.Sleep (200);
  53.             }
  54.            
  55.             // Inicio de bloque:
  56.             VisorDatos (DateTime.Now, "Bloqueo hasta que se complete el método asincrónico.");
  57.            
  58.             // Datos de completitud de método asincrónico:
  59.             DateTime completoEn = DateTime.MinValue;
  60.            
  61.             try
  62.             {
  63.                 completoEn = procesoLargo.EndInvoke (asyncResult);
  64.             }
  65.             catch
  66.             {
  67.                 // Aquí se trata la excepción en caso de que ocurra...
  68.             }
  69.            
  70.             // Informe final:
  71.             VisorDatos (completoEn, "Demostración técnica blocking finalizada");
  72.         }
  73.        
  74.         // Demostración del patrón (técnica) polling:
  75.         public static void Polling()
  76.         {
  77.             Console.WriteLine ("\n === Aplicación Técnica Polling === ");
  78.            
  79.             // Creación y encapsulamiento con delegado:
  80.             AsyncMetodosDelegate procesoLargo = ProcesoLargo;
  81.            
  82.             // Inicia la invocación asincrónica:
  83.             IAsyncResult asyncResult = procesoLargo.BeginInvoke (2000, "Blocking", null, null);
  84.            
  85.             // Mensaje de inicio de consulta:
  86.             VisorDatos (DateTime.Now, "La consulta se realiza mientras que el método asincrónico no haya finalizado");
  87.            
  88.             while (!asyncResult.IsCompleted)
  89.             {
  90.                 VisorDatos (DateTime.Now, "Polling...");
  91.                 Thread.Sleep (300);
  92.             }
  93.            
  94.             // Datos de completitud de método asincrónico:
  95.             DateTime completoEn = DateTime.MinValue;
  96.            
  97.             try
  98.             {
  99.                 completoEn = procesoLargo.EndInvoke (asyncResult);
  100.             }
  101.             catch
  102.             {
  103.                 // Aquí se trata la excepción en caso de que ocurra...
  104.             }
  105.            
  106.             // Informe final:
  107.             VisorDatos (completoEn, "Demostración técnica polling finalizada");
  108.         }
  109.        
  110.         // Demostración del patrón (técnica) Waiting:
  111.         public static void Waiting()
  112.         {
  113.             Console.WriteLine ("\n === Aplicación Técnica Waiting === ");
  114.            
  115.             // Creación y encapsulamiento con delegado:
  116.             AsyncMetodosDelegate procesoLargo = ProcesoLargo;
  117.            
  118.             // Inicia la invocación asincrónica:
  119.             IAsyncResult asyncResult = procesoLargo.BeginInvoke (2000, "Blocking", null, null);
  120.            
  121.             // Mensaje de inicio de consulta:
  122.             VisorDatos (DateTime.Now, "No se continua hasta que finalice el método asincrónico...");
  123.            
  124.             while (!asyncResult.AsyncWaitHandle.WaitOne(300, false))
  125.             {
  126.                 VisorDatos (DateTime.Now, "La espera superó los 300ms...");
  127.             }
  128.            
  129.             // Datos de completitud de método asincrónico:
  130.             DateTime completoEn = DateTime.MinValue;
  131.         }
  132.        
  133.         // Invocación del método ProcesoLargo múltiples veces:
  134.         public static void WaitAll()
  135.         {
  136.             Console.WriteLine ("\n === Demostración WaitAll === ");
  137.            
  138.             // Creación y encapsulamiento con delegado:
  139.             AsyncMetodosDelegate procesoLargo = ProcesoLargo;
  140.            
  141.             // Arreglo para mantener instancias IAsyncResult para cada
  142.             // uno de los métodos que se invocan asincrónicamente:
  143.             ArrayList asyncResultados = new ArrayList(3);
  144.            
  145.             // Agrega tres instancias de IAsyncResult:
  146.             asyncResultados.Add (procesoLargo.BeginInvoke (3000, "WaitAll 1", null, null));
  147.             asyncResultados.Add (procesoLargo.BeginInvoke (2500, "WaitAll 2", null, null));
  148.             asyncResultados.Add (procesoLargo.BeginInvoke (1500, "WaitAll 3", null, null));
  149.            
  150.             // Arreglo de objetos WaitHandle:
  151.             WaitHandle[] waitHandles = new WaitHandle[3];
  152.            
  153.             for (int i = 0; i < 3; ++i)
  154.             {
  155.                 waitHandles[i] = ((IAsyncResult)asyncResultados[i]).AsyncWaitHandle;
  156.             }
  157.            
  158.             // Espera a que todos los métodos asincrónicos finalicen:
  159.             VisorDatos (DateTime.Now, "Esperando a que los tres métodos finalicen...");
  160.            
  161.             while (!WaitHandle.WaitAll(waitHandles, 300, false))
  162.             {
  163.                 VisorDatos (DateTime.Now, "La espera superó los 300ms...");
  164.             }
  165.            
  166.             // Datos de completitud de método asincrónico:
  167.             DateTime completoEn = DateTime.MinValue;
  168.            
  169.             foreach (IAsyncResult resultado in asyncResultados)
  170.             {
  171.                 try
  172.                 {
  173.                     DateTime hora = procesoLargo.EndInvoke (resultado);
  174.                    
  175.                     if (hora > completoEn)
  176.                     {
  177.                         completoEn = hora;
  178.                     }
  179.                 }
  180.                 catch
  181.                 {
  182.                     // Aquí se trata la excepción en caso de que ocurra...
  183.                 }
  184.             }
  185.            
  186.             // Informe final:
  187.             VisorDatos (completoEn, "Demostración técnica WaitAll finalizada");
  188.         }
  189.        
  190.         // Demostración Callcack:
  191.         public static void Callback()
  192.         {
  193.             Console.WriteLine ("\n === Demostración Callback === ");
  194.            
  195.             // Creación y encapsulamiento con delegado:
  196.             AsyncMetodosDelegate procesoLargo = ProcesoLargo;
  197.            
  198.             IAsyncResult asyncResult = procesoLargo.BeginInvoke (2000, "Callback", CallbackHandler, procesoLargo);
  199.            
  200.             // Continua con otras tareas:
  201.             for (int i = 0; i < 15; ++i)
  202.             {
  203.                 VisorDatos (DateTime.Now, "Continua la ejecución de tareas...");
  204.                 Thread.Sleep (200);
  205.             }
  206.         }
  207.        
  208.         private static void CallbackHandler(IAsyncResult resultado)
  209.         {
  210.             // Recupera la isntancia del delegado:
  211.             AsyncMetodosDelegate procesoLargo = (AsyncMetodosDelegate) resultado.AsyncState;
  212.            
  213.             // Datos de completitud de método asincrónico:
  214.             DateTime completoEn = DateTime.MinValue;
  215.            
  216.             try
  217.             {
  218.                 completoEn = procesoLargo.EndInvoke (resultado);
  219.             }
  220.             catch
  221.             {
  222.                 // Aquí se trata la excepción en caso de que ocurra...
  223.             }
  224.            
  225.             // Informe final:
  226.             VisorDatos (completoEn, "Demostración técnica Callback finalizada");
  227.         }
  228.        
  229.         public static void Main()
  230.         {
  231.             // Ejecución de cada técnica determinación de completitud de invocación asincrónica:
  232.             Blocking();
  233.             Polling();
  234.             Waiting();
  235.             WaitAll();
  236.             Callback();
  237.            
  238.             // Esperar a finalizar:
  239.             Console.WriteLine (Environment.NewLine);
  240.             Console.WriteLine ("El método Main ha finalizado. Presione la tecla Enter para finalizar.");
  241.             Console.ReadLine();
  242.         }
  243.     }
  244. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement