C# - Cuatro patrones en ejecución asíncrona


He oído que hay cuatro patrones en la ejecución asíncrona .

"Hay cuatro patrones en la ejecución de delegados asíncronos: Sondeo, Espera de Finalización, Notificación de Finalización y "Disparar y Olvidar".

Cuando tengo el siguiente código :

class AsynchronousDemo
{
    public static int numberofFeets = 0;
    public delegate long StatisticalData();

    static void Main()
    {
        StatisticalData data = ClimbSmallHill;
        IAsyncResult ar = data.BeginInvoke(null, null);
        while (!ar.IsCompleted)
        {
            Console.WriteLine("...Climbing yet to be completed.....");
            Thread.Sleep(200);

        }
        Console.WriteLine("..Climbing is completed...");
        Console.WriteLine("... Time Taken for  climbing ....{0}", 
        data.EndInvoke(ar).ToString()+"..Seconds");
        Console.ReadKey(true);

    }


    static long ClimbSmallHill()
    {
        var sw = Stopwatch.StartNew();
        while (numberofFeets <= 10000)
        {
            numberofFeets = numberofFeets + 100;
            Thread.Sleep(10);
        }
        sw.Stop();
        return sw.ElapsedMilliseconds;
    }
}

1) ¿Cuál es el patrón del código anterior implementado ?

2) ¿Puedes explicar el código, cómo puedo implementar el resto ?.?

Author: Justin Niessner, 2009-11-23

3 answers

Lo que tienes ahí es el patrón de Sondeo. En este patrón continuamente preguntas " ¿Ya hemos llegado?"El bucle while está haciendo el bloqueo. El Thread.Sleep evita que el proceso consuma los ciclos de CPU.


Wait for Completion es el enfoque "I'll call you".

IAsyncResult ar = data.BeginInvoke(null, null);
//wait until processing is done with WaitOne
//you can do other actions before this if needed
ar.AsyncWaitHandle.WaitOne(); 
Console.WriteLine("..Climbing is completed...");

Así que tan pronto como WaitOne se llama, está bloqueando hasta que se complete la escalada. Puede realizar otras tareas antes de bloquear.


Con la Notificación de Finalización usted está diciendo " Usted me llama, Yo no te llamo."

IAsyncResult ar = data.BeginInvoke(Callback, null);

//Automatically gets called after climbing is complete because we specified this
//in the call to BeginInvoke
public static void Callback(IAsyncResult result) {
    Console.WriteLine("..Climbing is completed...");
}

No hay bloqueo aquí porque Callback va a ser notificado.


Y el fuego y el olvido serían

data.BeginInvoke(null, null);
//don't care about result

Tampoco hay bloqueo aquí porque no te importa cuando la escalada haya terminado. Como su nombre indica, te olvidas de ello. Estás diciendo "No me llames, no te llamaré, pero aún así, no me llames."

 88
Author: Bob,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-11-23 19:19:53
while (!ar.IsCompleted)
{
    Console.WriteLine("...Climbing yet to be completed.....");
    Thread.Sleep(200);
}

Eso es un sondeo clásico. - Comprobar, dormir, comprobar de nuevo,

 2
Author: Chris Cudmore,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-07-23 00:50:45

Este código es Polling:

while (!ar.IsCompleted)

Esa es la clave, sigue comprobando si está completada o no.

Este código no es realmente compatible con los cuatro, pero hay código que sí lo es.

Process fileProcess = new Process();
// Fill the start info
bool started = fileProcess.Start();

El método "Start" es Asincrónico. Genera un nuevo proceso.

Podríamos hacer cada una de las formas que solicitas con este código:

// Fire and forget
// We don't do anything, because we've started the process, and we don't care about it

// Completion Notification
fileProcess.Exited += new EventHandler(fileProcess_Exited);

// Polling
while (fileProcess.HasExited)
{

}

// Wait for completion
fileProcess.WaitForExit();
 0
Author: McKay,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-11-23 18:26:31