русс | укр

Мови програмуванняВідео уроки php mysqlПаскальСіАсемблерJavaMatlabPhpHtmlJavaScriptCSSC#DelphiТурбо Пролог

Компьютерные сетиСистемное программное обеспечениеИнформационные технологииПрограммирование


Linux Unix Алгоритмічні мови Архітектура мікроконтролерів Введення в розробку розподілених інформаційних систем Дискретна математика Інформаційне обслуговування користувачів Інформація та моделювання в управлінні виробництвом Комп'ютерна графіка Лекції


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


Дата додавання: 2015-01-08; переглядів: 1109.


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

Якщо при виклику BeginInvoke був вказаний метод зворотного виклику, цей метод викликається після завершення потоку. Метод зворотного виклику також задається за допомогою делегата, при цьому використовується стандартний делегат AsyncCallback. У методі, зворотного виклику для набуття повертаємого значення і вихідних параметрів застосовується метод EndInvoke.

Якщо метод зворотного виклику не був вказаний в параметрах методу BeginInvoke, метод EndInvoke можна використовувати в потоці, що ініціював запит. У лістингу 10.11 наводяться два приклади асинхронного виклику методу, що виконує розкладання числа на множники.

Клас Factorizer містить метод Factorize, що виконує розкладання на множники. Цей метод асинхронно викликається двома способами: у методі Num1 метод зворотного виклику задається в BeginInvoke, в методі Num2 мають місце очікування завершення потоку і безпосередній виклик EndInvoke.

 

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

using System;

using System.Threading;

using System.Runtime.Remoting.Messaging;

 

namespace AsynchroneDelegat

{

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

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)

{

m1 = 1; m2 = Num;

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

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

if (1 == m1) return false;

else return true;

}

}

// клас, одержуючий делегати і результати

public class PNum

{

private int Number;

public PNum(int number)

{

Number = number;

}

 

[OneWayAttribute()]

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

public void Res(IAsyncResult ar)

{

int m1, m2;

// отримання делегата з IAsyncResult

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

// отримання результатів виконання методу Factorize

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

// виведення результатів

Console.WriteLine("Перший спосіб: множетелі {0} : {1} {2}", Number, m1, m2);

}

 

}

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

public class Simple

{

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

public void Num1()

{

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, 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;

// отримання результатів виконання методу Fractorize

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

// виведення результатів

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

}

}

}

class Program

{

static void Main()

{

Simple s = new Simple();

s.Num1();

s.Num2();

}

 

}

}

 

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

Перший спосіб : множники 1000589023 : 7 142941289

Другий спосіб : множники 1000589023 : 7 142941289

 

Атрибут [OneWayAttribute()] позначає метод якщо не має повертаємого значення і вихідних параметрів.

 


<== попередня лекція | наступна лекція ==>
Клас Thread | РОЗДІЛ 11. РОБОТА З ФАЙЛАМИ


Онлайн система числення Калькулятор онлайн звичайний Науковий калькулятор онлайн