Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Where are CLR-defined methods like [delegate].BeginInvoke documented? [closed]

[EDIT, Completely rephrased:] Seems like my question was poorly worded indeed, and poorly received too. So I hope that this complete rephrasing helps...

MSDN tells clearly specifies: Control.BeginInvoke() Executes a delegate on the thread that the control's handle was created on, normally this would be the GUI thread. And Dispatcher.BeginInvoke() will run on the thread where the Dispatcher object was created. This would be any thread created by me.

But for delegates "the CLR automatically defines BeginInvoke and EndInvoke" and these calls run on a ThreadPool-thread instead. Apart from this slightly surprising different behaviour I wonder how I can find the specs of all functions that automatically get implemented.

For example: Intelli-sense shows that my delegate has a DynamicInvoke(). Class System.Delegate{} does have a DynamicInvoke() which might imply that my delegate inherits it. But Delegate{} has no BeginInvoke(). And Delegate{} has several functions that my delegate has not. Also my delegate gets a GetObjectData() method. And this seems to come from ISerializable.

So in conclusion, a delegate appears gets its methods from (1) the CLR "automatically", (2) some subset of Delegate{} possibly MulticastDelegate{}, and possibly (3) ISerializble. Where can I find a comprehensive specification of all methods a delegate gets? Especially interesting is BeginInvoke(), and it's exact signature, as the two aforementioned methods with that name have different sets of signatures.

[Someone suggested in an edit that a "delegate" is a "Delegate". I daresay, it is not.]

Thanks

like image 400
Adam Avatar asked Feb 19 '13 15:02

Adam


1 Answers

As per the subject of your question the answer would be these bold lines. MSDN might not be better but it is good though :)

Jeffrey Richter has written about what you asked in your question above. He has this article on MSDN magazine. http://msdn.microsoft.com/en-us/magazine/cc164139.aspx This article will show you an implementation of how actually (may be not actually but very close to) this BeginInvoke and EndInvoke actually is implemented in the .NET CLR. Invest some time in this article and after that I don't think now you need to read ahead. Jeffrey richter also has explained this all very well in his book CLR Via C#.

Most UI applications are single threaded. The controls on the UI can only be accessed using the thread with which they were created.

To acheive this Control.Invoke exists in Winforms. It will automatically invoke your code on the UI thread. In the WPF world, we don't have Control.Invoke. In WPF, we have the Dispatcher instead of Control.

Now delegate vs Delegate. Hans Passant has provided with a very nice answer.

So to dwell a little into it, I am writing this answer.

Delegate as mentioned on MSDN is a class. Lets take this code (taken from msdn http://msdn.microsoft.com/en-us/library/ms173171(v=vs.80).aspx )

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

As you can see here we have delegate (note with a small 'd'). This is a keyword to define a Delegate or to put it in simple words, This is a keyword to define a variable PerformCalculation that actually contains a reference to a Method.

I think you are already aware of this, but just for completeness.

Now to use this variable and invoke a method using code like this:

using System;
// Declare delegate -- defines required signature:
delegate void SampleDelegate(string message);

class TestDelegate
{
    private void CallMeUsingDelegate(string m_param)
    {
        Console.WriteLine("Called me using parameter - " + m_param);
    }

    public static void Main(string[] args)
    {
        // Here is the Code that uses the delegate defined above.
        SampleDelegate sd = new SampleDelegate(CallMeUsingDelegate);
        sd.Invoke("FromMain");
    }
}

Now to invoke a method you need to write a full Method as CallMeUsingDelegate method above. C# has this anonymous methods which can be used to invoke a method without actually having to write it as a method.

So the code above can also be written as

using System; // Declare delegate -- defines required signature: delegate void SampleDelegate(string message);

class TestDelegate
{
    public static void Main(string[] args)
    {
        // Here is the Code that uses the delegate defined above.
        SampleDelegate sd = delegate(param) {
                        Console.WriteLine("Called me using parameter - " + param);
                    };

        sd.Invoke("FromMain");
    }
}

This does the same work as the code above. But now we need to write some less code. The compiler will create identical IL code for the both the version above. But in the 2 case, the new method will have an autogenerated name by the compiler.

When it comes to BeginInvoke and EndInvoke, they are used to invoke methods asynchronously. This is done using threadpool which is available with the CLR.

Basically what happens is you call a method using

IAsyncResult ar = sd.BeginInvoke(CallMeUsingDelegate, callMeOnCompletion, sd);

Here Delegate is method that you are invoking. What will happen is that Thread of your program will call the BeginInvoke method which will internally invoke the method specified in the Delegate parameter on a CLR ThreadPool thread. Then you program continue running and returns an object that implements IAsyncResult interface. You can use this object to query about the progress of task invoked using your delegate ( note the Delegate sd passed as the 3 parameter ).

CallMeUsingDelegate method is invoked on a separate thread ( of ThreadPool ). When the task will complete, the ThreadPool will call the Callback method specified as 2 parameter.

Looking at all this you might think, why we need the EndInvoke then???

Well it is because if you don't call the EndInvoke, the CLR ThreadPool will hold a reference to this operation and you will leak some memory. So it always a good practice to call EndInvoke in the Callback method specified.

I hope this now clears (not all) but some thoughts.

like image 76
Dinesh Avatar answered Nov 03 '22 00:11

Dinesh