C # -Четыре шаблона в асинхронном исполнении

Я слышал, что существует четыре шаблона асинхронного выполнения.

Существует четыре шаблона в выполнении асинхронного делегата: опрос, ожидание завершения, уведомление о завершении и «активировать и забыть».

Когда у меня есть следующий код:

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) Какая модель реализована в приведенном выше коде?

2) Можете ли вы объяснить код, как я могу реализовать остальное ..?


person user215675    schedule 23.11.2009    source источник


Ответы (3)


У вас есть шаблон опроса. В этом шаблоне вы постоянно спрашиваете: «Мы уже на месте?» Цикл while выполняет блокировку. Thread.Sleep предотвращает перегрузку процессором циклов ЦП.


«Дождитесь завершения» - это подход «Я позвоню тебе».

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...");

Итак, как только вызывается WaitOne, вы блокируете его до тех пор, пока лазание не будет завершено. Перед блокировкой вы можете выполнить другие задачи.


С уведомлением о завершении вы говорите: «Звоните мне, я не буду вам звонить».

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...");
}

Здесь нет блокировки, потому что Callback получит уведомление.


И огонь и забыть будет

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

Здесь также нет блокировки, потому что вам все равно, когда лазание закончится. Как следует из названия, вы забываете об этом. Вы говорите: «Не звоните мне, я не буду звонить вам, но все же не звоните мне».

person Bob    schedule 23.11.2009
comment
Если вы не возражаете, можете сравнить эти модели с точки зрения затрат времени? - person user215675; 23.11.2009
comment
Что вы имеете в виду с точки зрения затрат времени? - person Bob; 23.11.2009
comment
Я обновил свой ответ. Чтобы быть ясным, ничто не будет блокировать другие потоки. Единственный поток, который будет заблокирован, - это тот, который хочет получить результат (который также запустил запрос). - person Bob; 23.11.2009
comment
Отличный ответ, одна маленькая вещь заключается в том, что (согласно вопросам о EndInvoke на SO) вы должны всегда вызывать EndInvoke. Это, конечно, полностью устраняет асинхронность, если вам всегда нужно блокировать, особенно с шаблоном «выстрелил и забыл». - person Chris S; 16.03.2010
comment
Не звоните мне, я не буду вам звонить, но все же не звоните мне (это не вы, это я. Думаю, нам стоит начать видеть другие темы) - person JJS; 16.02.2016
comment
Во втором подходе «Дождитесь завершения», как поживает WaitOne (), я вам позвоню? он делает медленный внутренний опрос? - person Mudit Jain; 28.07.2017

while (!ar.IsCompleted)
{
    Console.WriteLine("...Climbing yet to be completed.....");
    Thread.Sleep(200);
}

Это классический опрос. - Проверь, спи, еще раз проверь,

person Chris Cudmore    schedule 23.11.2009

Этот код - опрос:

while (!ar.IsCompleted)

Это ключ, вы продолжаете проверять, завершено ли оно.

Этот код на самом деле не поддерживает все четыре, но некоторый код поддерживает.

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

Метод «Пуск» - асинхронный. Это порождает новый процесс.

Мы можем использовать этот код любым из способов, которые вы запрашиваете:

// 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();
person McKay    schedule 23.11.2009