Интернет-журнал "Домашняя лаборатория", 2007 №6
Шрифт:
• AsyncCallback
Этот тип определен в System. Он может использоваться для делегирования вызова методу со следующей сигнатурой:
? один входной параметр типа IAsyncResult (тип определен в System);
? возвращаемое значение отсутствует (void).
В нашем случае делегаты данного типа будут использоваться для делегирования вызовов методам клиента Client::SumCallback и Client::MultCallback.
Метод
private static void SumCallback (IAsyncResult ar) {… }
клиента
Аналогично, метод
private static void MultCallback (IAsyncResult ar) {… }
клиента вызывается инфраструктурой асинхронных вызовов для уведомления клиента о том, что сделанный им ранее асинхронный вызов метода MuitBy2 сервера завершен также.
Клиент. Инициирование асинхронных вызовов
Прежде чем обсуждать завершение асинхронных вызовов уместно рассмотреть их инициирование. Для этого обратимся к коду метода Client::Main.
Прежде всего клиент выводит на консоль хеш основного потока
(Thread. CurrentThread. GetHashCode) и информацию о принадлежности данного потока классу рабочих потоков из пула потоков
(Thread.CurrentThread.IsThreadPoolThread)).
Далее создаются два делегата для инициирования асинхронных вызовов методов сервера. Делегат sum
HardFunction2Args sum = new HardFunction2Args(Server.Sum);
используется для асинхронного вызова метода Server::Sum, а делегат mult
HardFunctionlArg mult = new HardFunctionlArg(Server.MultBy2);
используется для асинхронного вызова метода Server::MultBy2.
Далее формируются делегаты sumCallback и multCallback
AsyncCallback sumCallback = new AsyncCallback(SumCallback);
AsyncCallback multCallback = new AsyncCallback(MultCallback);
которые будут использоваться инфраструктурой асинхронных вызовов для уведомления клиента о завершении соответственно Server::Sum и Server::MultBy2 вызовов.
Инициирование асинхронных вызовов производится клиентом следующим образом:
IAsyncResult arSum = sum.Beginlnvoke(3, 4, out sumResult, sumCallback, sum);
IAsyncResult arMult = mult.Beginlnvoke(5, out multResult, multCallback, mult);
Немного о делегатах в связи с асинхронными вызовами
Остановимся на некоторых вопросах, связанных с делегатами, имеющими отношение к асинхронным вызовам.
Делегаты sum и mult являются экземплярами ненаследуемых классов, производных от класса System.MuiticastDelegate. Система автоматически формирует эти классы, и, в том числе, реализации их методов Invoke, Begininvoke и EndInvoke.
Рассмотрим, для примера, сигнатуры этих методов для делегата sum:• public bool Invoke(int, int, out int)
Данный метод может использоваться для синхронного вызова метода Server::Sum. Первые два аргумента используются для передачи по значению суммируемых величин, последний — для передачи по ссылке результата, возвращаемое значение говорит об отсутствии переполнения.
В нашем случае этот метод будет вызван инфраструктурой асинхронных вызовов после инициирования вызова метода sum клиентом.
• public IAsyncResult Begininvoke(int, int, out int, AsyncCallback, Object)
Данный метод используется для инициирования асинхронного вызова метода Server::Sum клиентом.
Смысл первых трех параметров описан в предыдущем пункте.
Четвертый параметр служит для передачи ссылки на делегат типа AsyncCallback, который будет использоваться инфраструктурой асинхронных вызовов для вызова callback функции на стороне клиента для уведомления последнего о завершении вызова. Этот параметр может быть задан как null. В этом случае клиент может использовать другие способы получения уведомления о завершении вызова.
Последний параметр задает ссылку на некоторый объект, которая будет доступна из объекта, полученного как результат инициирования асинхронного метода. В данном случае мы будем тут задавать ссылку на делегат sum. Это позволит клиенту в рамках callback функции SumCallback получить доступ к делегату sum и завершить асинхронный вызов, вызвав метод EndInvoke. Если callback функция не используется, этот параметр можно задать равным null.
Возвращаемое значение типа IAsyncResult дает клиенту ссылку на объект, который может использоваться последним для получения информации о выполнении асинхронного вызова. В частности, свойство bool Completed {get; } интерфейса IAsyncResult может использоваться клиентом для опроса инфраструктуры асинхронных вызовов — возвращаемое значение равно true, если вызов завершен. Это один из способов получить информацию о завершении асинхронного вызова без использования callback функции.
• public bool EndInvoke(out int, IAsyncResult)
Данный метод вызывается клиентом для завершения асинхронного вызова Server::Sum и получения результатов. В нашем случае вызов этого метода выполняется в callback функции SumCallback.
Первый параметр — результат операции сложения, возвращаемое логическое значение равно true, если в процессе вычислений не произошло переполнения.
Последний параметр типа IAsyncResult задается клиентом. Это ссылка, полученная клиентом в результате инициирования асинхронного вызова путем вызова метода BeginInvoke.