Шрифт:
Методы BeginInvoke и EndInvoke обеспечивает возможность асинхронного вызова текущего метода во вторичном потоке выполнения. Если у вас есть опыт работы с многопоточными приложениями, вы должны знать, что одной из главных причин, по которым разработчики создают вторичные потоки, является вызов методов, для выполнения которых требуется много времени. И хотя библиотеки базовых классов .NET предлагают целое пространство имен (System.Threading), специально предназначенное для решения задач многопоточного программирования, с помощью делегатов соответствующие функциональные возможности использовать проще.
Но откуда компилятор "знает", как определять методы Invoke, BeginInvoke и EndInvoke? Чтобы понять суть процесса, рассмотрим пример автоматически генерируемого типа класса BinаrуОр (полужирным шрифтом здесь обозначены элементы, заданные определяемым типом делегата).
Во-первых, обратите внимание на то, что параметры и возвращаемое значение определяемого здесь метода Invoke соответствуют определению делегата BinaryOp. Первые параметры членов BeginInvoke (в данном случае это два целых числа) тоже соответствуют определению делегата BinaryOp, однако BeginInvoke всегда имеет еще два параметра (типа AsyncCallback и object), которые используются для асинхронного вызова методов. Наконец, возвращаемое значение метода EndInvoke тоже соответствует исходной декларации делегата, а единственным параметром метода является объект, реализующий интерфейс IAsyncResult.
Рассмотрим еще один пример. Предположим, что мы определили тип делегата, который позволяет указать на любой метод, возвращающий строку и имеющий три входных параметра System.Boolean.
На этот раз автоматически генерируемый класс выглядит так.
Делегаты могут также "указывать" на методы, содержащие любое число параметров out или ref. В качестве примера рассмотрим следующий тип делегата.
Сигнатуры методов Invoke и BeginInvoke выглядят так, как и ожидается, но обратите внимание на метод EndInvoke, который теперь включает и все аргументы out/ref, определенные типом делегата.
Итак, в результате определения делегата в C# компилятор генерирует изолированный класс с тремя методами, для которых возвращаемые значения и типы параметров соответствуют декларации делегата. Следующий псевдокод приближенно описывает соответствующий базовый шаблон.