Шаг 189 - Асинхронные вызовы

В прошлом шаге я рассказал, что на самом деле делегат является классом, про два метода которого я обещал рассказать. Так вот эти методы BeginInvoke и EndInvoke используются при написании в основном приложений с асинхронным вводом/выводом(с файлами, сокетами, вэбсервисами и т.д.).

Итак, метод BeginInvoke включает:

Первый - это делегат который вызывается после того как метод нашего делегата выполнился(то есть результаты вычислений доступны), а второй параметр доступен через проперти AsyncState интерфейса IAsyncResult возвращает метод IAsyncResult.

EndInvoke включает:

Возвращает вроде бы, как написано в SDK, тип нашего метода. К примеру:

public delegate void DelegateFoo(object obj, ref int IntValue);

Преобразуется к:

public class DelegateFoo : MultiCastDelegate
{
// здесь конструктор и всякая прочая чепуха смотри предыдущий шаг
	...... 
//методы для асинхронного вызова
public IAsyncResult BeginInvoke(object obj, ref int IntValue,
	AsyncCallback callback, Object object);
//заметьте в EndInvoke нет первого параметра
public void EndInvoke(ref int IntValue, IAsyncResult ar)
}

Итак, вызвав BeeginInvoke, мы можем продолжать работу нашего приложения, делегат будет выполнятся параллельно. Посмотрите в исходниках первый способ как это можно сделать, там всё вроде бы нормально, но если приложение закончило выполнятся, а наш делегат нет, что произойдёт? Наш делегат не закончив свою работу до конца, благополучно тоже прекратит своё существование. Поэтому если нам нужно обязательно дождаться, когда делегат выполнится нам нужно воспользоваться методом WaitOne(но можно и не только им, но в нашем случае я воспользовался им, этот метод и другие описаны в шаге про мьютекс кажется) интерфейса IAsyncResult(этот объект мы получаем после вызова BeginInvoke), который будет ждать завершение делегата определённое количество милисекунд, обязательно проверьте потом потом проперти IsCompleted этого интрфесйа, вдруг выполнение делегата, не закончилось ещё. Если нам нужно, чтобы он ждал бесконечно долго передайте первым параметром Timeout.Infinite.


Загрузить проект | Предыдущий Шаг | Следующий Шаг | Оглавление
Автор Leonid Molochniy - 04.12.2001