Краткий обзор делегатов .NET

Краткий обзор делегатов .NET

Напомним, что тип делегата .NET – это обеспечивающий типовую безопасность объектно-ориентированный указатель функции. Когда вы объявляете делегат .NET, компилятор C# отвечает на это созданием изолированного класса, полученного из System.MulticastDelegate (который, в свою очередь, является производным от System.Delegate). Эти базовые классы наделяют каждый делегат способностью поддерживать список адресов методов, которые могут быть вызваны позднее. Давайте рассмотрим декларацию делегата BinaryOp, который был впервые определен в главе 8.

// Тип делегата C#.

public delegate int BinaryOp(int x, int y);

В соответствии с данным определением BinaryOp может указывать на любой метод с двумя целочисленными аргументами, возвращающий целочисленное значение. После компиляции соответствующий компоновочный блок будет содержать полноценное определение класса, которое динамически генерируется на основе декларации делегата. В случае BinaryOp это определение класса будет выглядеть приблизительно так (приводится в псевдокоде).

sealed class BinaryOp: System.MulticastDelegate {

 public BinaryOp(object target, uint functionAddress);

 public void Invoke(int x, int y);

 public IAsyncResult BeginInvoke(int x, int y, AsyncCallback cb, object state);

 public int EndInvoke(IAsyncResult result);

}

Напомним, что генерируемый метод Invoke() используется для вызова методов, обслуживаемых объектом делегата в синхронном режиме. В этом случае вызывающий поток (например, первичный поток приложения) вынужден ждать, пока не завершится вызов делегата. Также напомним, что в C# метод Invoke() не вызывается в программном коде явно, а запускается в фоновом режиме при использовании "нормального синтаксиса" вызова метода. Рассмотрите следующий программный код, в котором статический метод Add() вызывается в синхронной (т.е. блокирующей) форме.

// Это требуется для вызова Thread.Sleep().

using System.Threading;

using System;

namespace SyncDelegate {

 public delegate int BinaryOp(int x, int y);

 class Program {

  static void Main(string[] args) {

   Console.WriteLine("***** Синхронный вызов, делегата *****");

   // Вывод ID выполняемого потока.

   Console.WriteLine("Вызван Main() в потоке {0}.", Thread.CurrentThread.GetHashCode());

   // Вызов Add() в синхронной форме.

   BinaryOp b = new BinaryOp(Add);

   int answer = b(10, 10);

   // Эти строки не будут выполнены до завершения

   // работы метода Add().

   Console.WriteLine("В Main() еще есть работа!");

   Console.WriteLine("10 + 10 равно {0}.", answer);

   Console.ReadLine();

  }

  static int Add(int x, int y) {

   // Вывод ID выполняемого потока.

Console.WriteLine("Вызван Add() в потоке {0}.", Thread.CurrentThread.GetHashCode());

   // Пауза примерно 5 секунд для

   // имитации длительной операции.

   Thread.Sleep(5000);

   return x + у;

  }

 }

}

Сначала заметим, что в этой программе используется пространство имен System.Threading. В методе Add() вызывается статический метод Thread.Sleep(), чтобы приостановить вызывающий поток (приблизительно) на пять секунд для имитации задачи, выполнение которой требует много времени. Поскольку метод Add() вызывается в синхронной форме, метод Main() не напечатает результат операции до тех пор, пока не завершится работа метода Add().

Далее заметим, что метод Main() получает доступ к текущему потоку (с помощью Thread.CurrentThread) и печатает его хешированный код. Поскольку этот хешированный код представляет объект в конкретном состоянии, соответствующее значение можно использовать как "грубый" идентификатор потока. Та же логика используется в статическом методе Add(). Как и следует ожидать, поскольку вся работа в этом приложении выполняется исключительно первичным потоком, вы увидите одинаковые хешированные значения в консольном выводе программы (рис. 14.1).

Рис. 14.1. Синхронные вызовы методов "блокируют" другие вызовы

При выполнении этой программы вы заметите, что перед тем выполнением Console.WriteLine() произойдет пятисекундная задержка. И хотя многие методы (если не подавляющее их большинство) могут вызваться синхронно совершенно безболезненно, делегатам .NET, если это необходимо, можно дать указание вызывать методы асинхронно.

Исходный код. Проект SyncDelegate размещен в подкаталоге, соответствующем главе 14.

Поделитесь на страничке

Следующая глава >

Похожие главы из других книг

5.1 Знакомство и Краткий Обзор

Из книги C++ автора Хилл Мюррей

5.1 Знакомство и Краткий Обзор Предназначение понятия класса, которому посвящены эта и две последующие главы, состоит в том, чтобы предоставить программисту инструмент для создания новых типов, столь же удобных в обращении сколь и встроенные типы. В идеале тип оределяемый


Краткий обзор

Из книги Каждому проекту своя методология автора Коуберн Алистэр

Краткий обзор "Методология с большой буквы" - это название того, как организация многократно производит и поставляет программные системы: кого в ней нанимают на работу и зачем, чего ожидают люди от своих коллег, какие условности они соблюдают, начиная от размещения


Глава 10. Краткий обзор

Из книги Экстремальное программирование автора Бек Кент

Глава 10. Краткий обзор Мы будем опираться на симбиоз взаимодействующих между собой методик. Методик, некоторые из которых были забыты десятилетия назад как непрактичные и наивные.Вот исходные материалы, из которых нам предстоит построить новую дисциплину разработки


Краткий обзор технологий

Из книги Разгони свой сайт автора Мациевский Николай

Краткий обзор технологий При этом все основные методы можно разбить на 6 групп (каждая из которых позволяет решить одну из заявленных задач).Уменьшение размера объектов. Здесь фигурируют сжатие и методы оптимизации изображений, подробнее об этом можно прочитать во


Видимые и невидимые части компьютера. Краткий обзор

Из книги Железо ПК [Популярный самоучитель] автора Пташинский Владимир

Видимые и невидимые части компьютера. Краткий обзор Итак, перед вами компьютер (см. рис. 1.1). Возможно, ваша машина внешне отличается от приведенной на рис. 1.1, но, скорее всего, незначительно. Чтобы убедиться в этом, предлагаем провести что-то типа переклички. Перечислим


Краткий обзор представленных материалов

Из книги Применение Windows API автора Легалов А И

Краткий обзор представленных материалов Разработка программ зачастую напоминает священный ритуал, построенный на произнесении ряда обязательных магических заклинаний. Особенно это касается Windows приложений. Windows-заклинания позволяют вывести графическое окно,


3.3 Краткий обзор интерфейса

Из книги Руководство по переходу на Ubuntu 10.04 LTS «Lucid Lynx» автора Неворотин Вадим

3.3 Краткий обзор интерфейса Если вы работали с другими операционными системами, полагаю, вы легко разберётесь в интерфейсе Ubuntu. Подробное знакомство с ним мы проведём после установки, а пока обратите внимание на главное меню системы в левом верхнем углу: Рис. 3.6: Главное


Краткий обзор класса TList

Из книги Фундаментальные алгоритмы и структуры данных в Delphi автора Бакнелл Джулиан М.

Краткий обзор класса TList Класс TList хранит указатели в формате массива. Указатели могут быть любыми. Они могут указывать на записи, строки или объекты. Класс имеет специальные методы для вставки и удаления элементов, поиска элемента в списке, перестановки элементов и, в


3.1. Краткий обзор интерфейса

Из книги Windows Vista. Для профессионалов автора Клименко Роман Александрович

3.1. Краткий обзор интерфейса Опытный пользователь, не первый год работающий с операционной системой Windows ХР, при переходе на новую операционную систему Windows Vista может немного растеряться. Действительно, несмотря на то что ничего революционного и кардинально нового в


Первый просмотр: краткий обзор

Из книги Язык Си - руководство для начинающих автора Прата Стивен

Первый просмотр: краткий обзор #include — включение другого файла.Эта строка указывает компилятору, что нужно включить информацию, содержащуюся в файле stdio.h.main() — имя функции РИС. 2.1. Структура программы, написанной на языке Си.Любая программа, написанная на языке Си,


typedef - КРАТКИЙ ОБЗОР

Из книги Как сделать свой сайт и заработать на нем. Практическое пособие для начинающих по заработку в Интернете автора Мухутдинов Евгений

typedef - КРАТКИЙ ОБЗОР      Функция typedef позволяет нам создать свое собственное имя типа. Это напоминает директиву #define, но со следующими тремя изменениями:1. В отличие от #define функция typedef дает символические имена, но ограничивается только типами данных.2. Функция typedef


2. Краткий обзор С++

Из книги автора

2. Краткий обзор С++ Эту главу мы начнем с рассмотрения встроенного в язык С++ типа данных “массив”. Массив – это набор данных одного типа, например массив целых чисел или массив строк. Мы рассмотрим недостатки, присущие встроенному массиву, и напишем для его


12.1. Краткий обзор

Из книги автора

12.1. Краткий обзор Реализация обобщенного алгоритма не зависит от типа контейнера, поэтому одна основанная на шаблонах реализация может работать со всеми контейнерами, а равно и со встроенным типом массива. Рассмотрим алгоритм find(). Если коллекция не отсортирована, то,