Интернет-журнал "Домашняя лаборатория", 2007 №6
Шрифт:
}
}
Комментарии к коду.
Сервер и клиент представлены соответственно классами Server и Client.
Сервер
Сервер реализует два статических метода:
• Метод public static bool Sum(int x, int у, out int z) {… } обеспечивает сложение двух чисел типа int.
Временная сложность проводимых вычислений имитируется с помощью вызова Thread.Sleер(1000).
В самом начале, еще до проведения вычислений, на консоль выводится хеш потока, выполняющего вызов (Thread.CurrentThread.GetHashCode), и информация о принадлежности данного потока классу рабочих потоков из пула потоков (Thread.CurrentThread.IsThreadPoolThread)).
• Метод public static bool MuitBy2(int x, out int y) {… } обеспечивает умножение числа на 2 и реализован аналогично предыдущему методу.
Здесь важно отметить, что разработчик сервера не заботится о том, как именно будут вызываться методы сервера клиентами — синхронно или асинхронно. Все зависит от клиента. Он может вызывать методы сервера как синхронно, так и асинхронно.
Клиент. Типы используемых делегатов
В данном примере клиент вызывает методы сервера асинхронно, что достигается за счет использования делегатов.
В коде клиента используются делегаты трех типов:
• HardFunction2Args
Этот тип определяется в классе client:
private delegate bool HardFunction2Args (int x, int y, out int result);
Данный делегат может делегировать вызов (как синхронный так и асинхронный) любому методу (как статическому так и нестатическому) любого класса с заданной сигнатурой (два входных параметра типа int, один выходной типа int, возвращаемое значение типа bool). В нашем случае вызов будет делегироваться методу Server::Sum.
• HardFunctionlArg
Этот тип также определяется в классе Client:
private delegate bool HardFunctionlArg (int x, out int result);
Данный делегат может делегировать вызов (как синхронный так и асинхронный) любому методу (как статическому так и нестатическому) любого класса с заданной сигнатурой (один входной параметр типа int, один выходной типа int, возвращаемое значение типа bool). В данном случае вызов будет делегироваться методу Server::MultBy2.
• AsyncCallback
Этот тип определен в System. Он может использоваться для делегирования вызова методу со следующей сигнатурой:
? один входной параметр типа IAsyncResult (тип определен в System);
? возвращаемое значение отсутствует (void).
В нашем случае делегаты данного типа будут использоваться для делегирования вызовов методам клиента Client::SumCallback и Client::MultCallback.
Метод
private static void SumCallback (IAsyncResult ar) {… }
клиента вызывается инфраструктурой асинхронных вызовов для уведомления клиента о том, что сделанный им ранее асинхронный вызов метода sum сервера завершен.
Аналогично, метод
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);