tags:

views:

683

answers:

2

e.g. if you write...
public delegate void MyTypedDel(int x)
Intellisense shows that BeginInvoke, Invoke and EndInvoke are part of the MyTypedDel type definition.
They are not part of the Delegate or MulticastDelegate type definition. (Delegate has a DynamicInvoke method, which uses late/runtime binding to bind to a method.)

So my question is where are these methods mixed in to the typed delegate type definition and how does its implementation look like? I read that... Invoke internally calls BeginInvoke and EndInvoke in succession on the same thread. Is this true?

Just curious as to the magic under the hood here.. Maybe I missed something real obvious... in which case be brutal :)

+4  A: 

The compiler generates your delegate class, which extends the Delegate BCL class and adds methods specific to the signature of your delegate. You can see this by looking at your delegate (or a BCL delegate) in reflector and switching to IL view (since the C# disassembler is smart enough to turn it back into a delegate declaration). Example:

.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
    {
    }

}

HTH, Kent

Kent Boogaart
Why are the .method blocks empty.. as in where is the implementation/IL for these methods? Where are these calls routed to ?
Gishu
I think it's related to the runtime managed metadata. I'm guessing that's equivalent to an InternalCall, meaning the CLR implements those methods internally.
Kent Boogaart
ooh.. more magic dust ;) Thanks for replying... helpful.
Gishu
Found my answer in CLR via C# 2.0 by Jeffrey Richter - Chapter on Delegates. When you use the delegate keyword, the compiler creates a new Type derived from MulticastDelegate and adds a ctor, Invoke() with the same signature as the delegate you specifed and the corresponding BeginInvoke() and EndInvoke().
Gishu
+1  A: 

The compiler does most of this work (see Kent's reply). Re the question about calling Begin/End in succession; no, not for delegates. You can verify this, because BeginInvoke pushes the work onto the ThreadPool, where-as if you use Invoke the work happens on the current thread.

This approach, however, is common some other Begin/End pairs (in particular IO-bound operations); but not for delegates.

I've been looking at more graceful ways of calling Begin/End (without messing with IAsyncResult etc) - see here for more.

Marc Gravell