Асинхронные делегаты

Делегат можно вызвать на выполнение либо синхронно, как во всех приведенных ранее примерах, либо асинхронно с помощью методов BeginInvoke и EndInvoke. При вызове делегата с помощью метода BeginInvoke среда выполнения создает для исполнения метода отдельный поток и возвращает управление оператору» следующему за вызовом. При этом в исходном потоке можно продолжать вычис­ления.

Если при вызове BeginInvoke был указан метод обратного вызова, этот метод вызы­вается после завершения потока. Метод обратного вызова также задается с помо­шью делегата, при этом используется стандартный делегат AsyncCallback. В методе обратного вызова для получения возвращаемого значения и выходных парамет­ров применяется метод EndInvoke.

Если метод обратного вызова не был указан в параметрах метода BeginInvoke, ме­тод EndInvoke можно использовать в потоке, инициировавшем запрос.

В листинге 10.11 приводятся два примера асинхронного вызова метода, выпол­няющего разложение числа на множители. Листинг приводится по документа­ции Visual Studio с некоторыми изменениями.

Класс Factorizer содержит метод Factorize, выполняющий разложение на мно­жители. Этот метод асинхронно вызывается двумя способами: в методе Num1 ме­тод обратного вызова задается в BeginInvoke, в методе Num2 имеют место ожидание завершения потока и непосредственный вызов EndInvoke.

Листинг 10.11. Асинхронные делегаты

using System;

using System.Threading;

using System.Runtime.Remoting.Messaging;

// асинхронный делегат public

delegate bool AsyncDelegate(int Num, out int m1, out int m2);

// класс, выполняющий разложение числа на множители

public class Factorizer

{

public bool Factorize(int Num, out int m1, out int m2)

{

ml = 1; m2 = Num;

for (int i = 2; i < Num; i++)

if (0 == (Num % i)) { ml = i; m2 = Num / i; break; }

if (1 == ml) return false; else return true;

}

}

// класс, получающий делегата и результаты

public class PNum

{

private int Number;

public PNum(int number)

{ Number = number; }

[OneWayAttribute()]

// метод, получающий результаты

public void Res(IAsyncResult ar)

{

int ml, m2;

// получение делегата из AsyncResult

AsyncDelegate ad = (AsyncDelegate)((AsyncResult)ar).AsyncDelegate;

// получение результатов выполнения метода Factorize a

d.EndInvoke(out m1, out m2, ar);

// вывод результатов

Console.WriteLine("Первый способ: множители {0}: {1} {2}",

Number, ml, m2);

}

// демонстрационный класс

public class Simple

{

// способ 1: используется функция обратного вызова

public void Num1()

{

Factorizer f = new Factonzer();

AsyncDelegate ad = new AsyncDelegate(f.Factorize);

int Num = 1000589023, tmp;

// создание экземпляра класса, который будет вызван

// после завершения работы метода Factorize

PNum n = new PNum(Num);

// задание делегата метода обратного вызова

AsyncCallback callback = new AsyncCallback(n.Res);

// асинхронный вызов метода Factorize

IAsyncResult ar = ad.BeginInvoke(Num, out tmp, out tmp,

callback, null);

}

//

// здесь - выполнение неких дальнейших действий

//...

// способ 2: используется ожидание окончания выполнения

public void Num2()

{

Factorizer f = new Factorizer();

AsyncDelegate ad = new AsyncDelegate(f.Factorize);

int Num = 1000589023, tmp;

// создание экземпляра класса, который будет вызван

// после завершения работы метода Factorize

PNum n = new PNum(Num);

// задание делегата метода обратного вызова

AsyncCallback callback = new AsyncCallback(n.Res);

// асинхронный вызов метода Factorize

IAsyncResult ar = ad.BeginInvoke(Num, out tmp, out tmp,

null, null);

// ожидание завершения

ar.AsyncWaitHandle.WaitOne(10000, false);

if (ar.IsCompleted)

{

int m1, m2;

// получение результатов выполнения метода Factorize

ad.EndInvoke(out ml, out m2, ar);

// вывод результатов

Console.WriteLine("Второй способ: множители {0}: {1} {2}", Num, ml, m2);

}

}

public static void Main()

{

Simple s = new Simple();

s.Num1();

s.Num2();

}

}

}

Результат работы программы:

Первый способ: множители 1000589023: 7 142941289

Второй способ: множители 1000589023: 7 142941289


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: