2009-03-25 1 views
3

, например. если вы пишете ...
public delegate void MyTypedDel(int x)
Intellisense показывает, что BeginInvoke, Invoke и EndInvoke являются частью определения типа MyTypedDel.
Они не являются частью определения типа делегата или MulticastDelegate. (Делегат имеет метод DynamicInvoke, который использует привязку позднего/времени выполнения для привязки к методу.)Кто добавляет определения метода BeginInvoke, Invoke и EndInvoke к типизированному делегату?

Итак, мой вопрос в том, где эти методы смешиваются с типизированным определением типа делегата и как выглядит его реализация? Я прочитал, что ... Invoke внутренне вызывает BeginInvoke и EndInvoke последовательно в том же потоке. Это правда?

Просто любопытно, как к магии под капотом здесь .. Может быть, я пропустил что-то реальное очевидное ... в этом случае быть жестокой :)

ответ

5

компилятор генерирует свой класс делегата, который расширяет Delegate BCL класс и добавляет методы, специфичные для подписи вашего делегата. Вы можете увидеть это, посмотрев на своего делегата (или делегата BCL) в отражателе и переключитесь на просмотр IL (поскольку дизассемблер C# достаточно умен, чтобы превратить его обратно в объявление делегата). Пример:

.class public auto ansi sealed WaitCallback 
    extends System.MulticastDelegate 
{ 
    .custom instance void System.Runtime.InteropServices.ComVisibleAttribute::.ctor(bool) = { bool(true) } 
    .method public hidebysig specialname rtspecialname instance void .ctor(object 'object', native int 'method') runtime managed 
    { 
    } 

    .method public hidebysig newslot virtual instance class System.IAsyncResult BeginInvoke(object state, class System.AsyncCallback callback, object 'object') runtime managed 
    { 
    } 

    .method public hidebysig newslot virtual instance void EndInvoke(class System.IAsyncResult result) runtime managed 
    { 
    } 

    .method public hidebysig newslot virtual instance void Invoke(object state) runtime managed 
    { 
    } 

} 
+0

Почему блоки .method пустые .. как в где реализация/IL для этих методов? Куда направляются эти вызовы? – Gishu

+0

Я думаю, что это связано с управляемыми метаданными времени выполнения. Я предполагаю, что это эквивалентно InternalCall, то есть CLR реализует эти методы внутренне. –

+0

ooh .. более волшебная пыль;) Спасибо за ответ ... полезный. – Gishu

1

Компилятор выполняет большую часть этой работы (см. Ответ Кента). Возьмем вопрос о вызове Begin/End подряд; нет, не для делегатов. Вы можете это проверить, потому что BeginInvoke толкает работу на ThreadPool, где, как если бы вы использовали Invoke, работа происходит в текущем потоке.

Этот подход, однако, является общим для некоторых других пар Begin/End (в частности, операций с IO-привязкой); но не для делегатов.

Я искал более изящные способы вызова Begin/End (без возиться с IAsyncResult и т. Д.) - see here for more.

Смежные вопросы