litbaza книги онлайнРазная литератураИнтернет-журнал "Домашняя лаборатория", 2007 №6 - Вязовский

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать
1 ... 245 246 247 248 249 250 251 252 253 ... 361
Перейти на страницу:
class="p1">        try {

             у = checked((int) (x*2));

        }

        catch (Exception) {

             return false;

         }

         return true;

     }

}

Public class Client {

       private static int workCount = 0;

       private delegate bool HardFunction2Args (

            int x, int y, out int result);

       private delegate bool HardFunctionlArg (

            int x, out int result);

       private static void SumCallback(IAsyncResult ar) {

             int z;

             HardFunction2Args sum =

                (HardFunction2Args)ar.AsyncState;

             bool result = sum.Endlnvoke(out z, ar);

             if (result) Console.WriteLine (

                  "SumCallback: Sum = " + z);

             else Console.WriteLine (

                  "SumCallback: Bad arguments for Server.Sum

             workCount++;

        }

        private static void MultCallback(IAsyncResult ar) {

             int z;

             HardFunctionlArg mult =

                   (HardFunctionlArg)ar.AsyncState;

             bool result = mult.Endlnvoke(out z, ar);

             if (result) Console.WriteLine (

                  "MultCallback: MultBy2 = " + z);

             else Console.WriteLine (

                  "MultCallback: Bad argument for MultBy2");

              workCount++;

        }

        public static void Main() {

             int sumResult, multResult, count = 0;

             Console.WriteLine("Client thread = " +

                    Thread.CurrentThread.GetHashCode() + PoolThread = "+

                    Thread.CurrentThread.IsThreadPoolThread);

              HardFunction2Args sum =

                     new HardFunction2Args(Server.Sum);

              HardFunctionlArg mult =

                     new HardFunctionlArg(Server.MultBy2);

              AsyncCallback sumCallback =

                     new AsyncCallback(SumCallback);

              AsyncCallback multCallback =

                     new AsyncCallback(MultCallback);

              IAsyncResult arSum = sum.Beginlnvoke(3, 4,

                     out sumResult, sumCallback, sum);

               IAsyncResult arMult = mult.Beginlnvoke(5,

                      out multResult, multCallback, mult);

               while (workCount < 2) {

                       Console.WriteLine("Client thread: count = "+ count++);

                       Thread.Sleep(100);

              }

              Console.WriteLine("Bye!");

        }

}

Комментарии к коду.

Сервер и клиент представлены соответственно классами Server и Client.

Сервер

Сервер реализует два статических метода:

• Метод public static bool Sum(int x, int у, out int z) {… } обеспечивает сложение двух чисел типа int. Результат записывается в переменную z типа int. В случае возникновения переполнения возвращается false, при его отсутствии — true.

Временная сложность проводимых вычислений имитируется с помощью вызова 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);

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. Первые два аргумента используются

1 ... 245 246 247 248 249 250 251 252 253 ... 361
Перейти на страницу:

Комментарии
Минимальная длина комментария - 20 знаков. Уважайте себя и других!
Комментариев еще нет. Хотите быть первым?