Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using System.Threading;
- using System.Collections;
- namespace Recetas.Cap04
- {
- public sealed class TecnicasInvocacionAsincronica
- {
- // Método utilitario para la presentación de datos
- // de ejecución de los métodos con ejecución asincrónica:
- private static void VisorDatos(DateTime hora, string mensaje)
- {
- Console.WriteLine ("[{0,3}/{1}] - {2} : {3}", Thread.CurrentThread.ManagedThreadId,
- Thread.CurrentThread.IsThreadPoolThread ? "pool" : "principal",
- hora.ToString ("HH:mm:ss.ffff"), mensaje);
- }
- // Delegado para permitir la ejecución de métodos
- // con la firma compatible:
- public delegate DateTime AsyncMetodosDelegate(int retraso, string nombre);
- // Método que simula la ejecución de una tarea que toma
- // varios segundos:
- public static DateTime ProcesoLargo (int retraso, string nombre)
- {
- VisorDatos (DateTime.Now, String.Format ("{0} - thread en ejecución."));
- // Simula la ejecución de tareas que toman tiempo:
- Thread.Sleep (retraso);
- VisorDatos (DateTime.Now, String.Format ("{0} - thread finalizado."));
- return DateTime.Now;
- }
- // Aplicación del patrón (técnica) de determinación de completidud
- // de invocación asincrónica `Blocking`:
- public static void Blocking()
- {
- Console.WriteLine ("\n === Aplicación Técnica Blocking === ");
- // Creación y encapsulamiento con delegado:
- AsyncMetodosDelegate procesoLargo = ProcesoLargo;
- // Inicia la invocación asincrónica:
- IAsyncResult asyncResult = procesoLargo.BeginInvoke (2000, "Blocking", null, null);
- // Antes de que se realice el bloqueo se ejecutan estas instrucciones:
- for (int i = 0; i < 3; ++i)
- {
- VisorDatos (DateTime.Now, "Continua ejecutándose antes de bloquearse...");
- Thread.Sleep (200);
- }
- // Inicio de bloque:
- VisorDatos (DateTime.Now, "Bloqueo hasta que se complete el método asincrónico.");
- // Datos de completitud de método asincrónico:
- DateTime completoEn = DateTime.MinValue;
- try
- {
- completoEn = procesoLargo.EndInvoke (asyncResult);
- }
- catch
- {
- // Aquí se trata la excepción en caso de que ocurra...
- }
- // Informe final:
- VisorDatos (completoEn, "Demostración técnica blocking finalizada");
- }
- // Demostración del patrón (técnica) polling:
- public static void Polling()
- {
- Console.WriteLine ("\n === Aplicación Técnica Polling === ");
- // Creación y encapsulamiento con delegado:
- AsyncMetodosDelegate procesoLargo = ProcesoLargo;
- // Inicia la invocación asincrónica:
- IAsyncResult asyncResult = procesoLargo.BeginInvoke (2000, "Blocking", null, null);
- // Mensaje de inicio de consulta:
- VisorDatos (DateTime.Now, "La consulta se realiza mientras que el método asincrónico no haya finalizado");
- while (!asyncResult.IsCompleted)
- {
- VisorDatos (DateTime.Now, "Polling...");
- Thread.Sleep (300);
- }
- // Datos de completitud de método asincrónico:
- DateTime completoEn = DateTime.MinValue;
- try
- {
- completoEn = procesoLargo.EndInvoke (asyncResult);
- }
- catch
- {
- // Aquí se trata la excepción en caso de que ocurra...
- }
- // Informe final:
- VisorDatos (completoEn, "Demostración técnica polling finalizada");
- }
- // Demostración del patrón (técnica) Waiting:
- public static void Waiting()
- {
- Console.WriteLine ("\n === Aplicación Técnica Waiting === ");
- // Creación y encapsulamiento con delegado:
- AsyncMetodosDelegate procesoLargo = ProcesoLargo;
- // Inicia la invocación asincrónica:
- IAsyncResult asyncResult = procesoLargo.BeginInvoke (2000, "Blocking", null, null);
- // Mensaje de inicio de consulta:
- VisorDatos (DateTime.Now, "No se continua hasta que finalice el método asincrónico...");
- while (!asyncResult.AsyncWaitHandle.WaitOne(300, false))
- {
- VisorDatos (DateTime.Now, "La espera superó los 300ms...");
- }
- // Datos de completitud de método asincrónico:
- DateTime completoEn = DateTime.MinValue;
- }
- // Invocación del método ProcesoLargo múltiples veces:
- public static void WaitAll()
- {
- Console.WriteLine ("\n === Demostración WaitAll === ");
- // Creación y encapsulamiento con delegado:
- AsyncMetodosDelegate procesoLargo = ProcesoLargo;
- // Arreglo para mantener instancias IAsyncResult para cada
- // uno de los métodos que se invocan asincrónicamente:
- ArrayList asyncResultados = new ArrayList(3);
- // Agrega tres instancias de IAsyncResult:
- asyncResultados.Add (procesoLargo.BeginInvoke (3000, "WaitAll 1", null, null));
- asyncResultados.Add (procesoLargo.BeginInvoke (2500, "WaitAll 2", null, null));
- asyncResultados.Add (procesoLargo.BeginInvoke (1500, "WaitAll 3", null, null));
- // Arreglo de objetos WaitHandle:
- WaitHandle[] waitHandles = new WaitHandle[3];
- for (int i = 0; i < 3; ++i)
- {
- waitHandles[i] = ((IAsyncResult)asyncResultados[i]).AsyncWaitHandle;
- }
- // Espera a que todos los métodos asincrónicos finalicen:
- VisorDatos (DateTime.Now, "Esperando a que los tres métodos finalicen...");
- while (!WaitHandle.WaitAll(waitHandles, 300, false))
- {
- VisorDatos (DateTime.Now, "La espera superó los 300ms...");
- }
- // Datos de completitud de método asincrónico:
- DateTime completoEn = DateTime.MinValue;
- foreach (IAsyncResult resultado in asyncResultados)
- {
- try
- {
- DateTime hora = procesoLargo.EndInvoke (resultado);
- if (hora > completoEn)
- {
- completoEn = hora;
- }
- }
- catch
- {
- // Aquí se trata la excepción en caso de que ocurra...
- }
- }
- // Informe final:
- VisorDatos (completoEn, "Demostración técnica WaitAll finalizada");
- }
- // Demostración Callcack:
- public static void Callback()
- {
- Console.WriteLine ("\n === Demostración Callback === ");
- // Creación y encapsulamiento con delegado:
- AsyncMetodosDelegate procesoLargo = ProcesoLargo;
- IAsyncResult asyncResult = procesoLargo.BeginInvoke (2000, "Callback", CallbackHandler, procesoLargo);
- // Continua con otras tareas:
- for (int i = 0; i < 15; ++i)
- {
- VisorDatos (DateTime.Now, "Continua la ejecución de tareas...");
- Thread.Sleep (200);
- }
- }
- private static void CallbackHandler(IAsyncResult resultado)
- {
- // Recupera la isntancia del delegado:
- AsyncMetodosDelegate procesoLargo = (AsyncMetodosDelegate) resultado.AsyncState;
- // Datos de completitud de método asincrónico:
- DateTime completoEn = DateTime.MinValue;
- try
- {
- completoEn = procesoLargo.EndInvoke (resultado);
- }
- catch
- {
- // Aquí se trata la excepción en caso de que ocurra...
- }
- // Informe final:
- VisorDatos (completoEn, "Demostración técnica Callback finalizada");
- }
- public static void Main()
- {
- // Ejecución de cada técnica determinación de completitud de invocación asincrónica:
- Blocking();
- Polling();
- Waiting();
- WaitAll();
- Callback();
- // Esperar a finalizar:
- Console.WriteLine (Environment.NewLine);
- Console.WriteLine ("El método Main ha finalizado. Presione la tecla Enter para finalizar.");
- Console.ReadLine();
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement