The definition of a delegate must be known. It is essentially a class. We define a delegate:
1 Delegate Int Decrement ( Int X, Int Y );
After compilation, the compiler automatically generates a sealed class inherited from multicastdelegate:
1 Sealed Class Decrement: multicastdelegate
2 {
3 }
So what Members should the decrement class contain? After analysis, the complete decrement class generated by the compiler should be as follows:
Complete decrement class
1 Sealed Class Decrement: multicastdelegate
2 {
3 Public Decrement ( Object Target, Uint Functionaddresss ); // Constructor
4 Public Int Invoke ( Int X, Int Y ); // Synchronous call delegate Method
5 Public Iasyncresult begininvoke ( Int X, Int Y, asynccallback CB, Object State ); // Asynchronous call delegate Method
6 Public Int Endinvoke (iasyncresult AR ); // End the call of the delegate method Asynchronously
7
8 }
We know that the multicastdelegate class is inherited from the delegate class. They are all abstract, but we cannot show that new classes are derived from them. Only the compiler can do this. View msdn, we know that the delegate class has two important public attributes: Target and method. Target is of the object type and method is of the system type. reflection. methodinfo type (this type usually refers to a method. If you are familiar with reflection, it should be clear). method indicates the method bound to the delegate, that is, when the delegate variable is created, the parameter passed to the constructor. this parameter is usually a function name. Target refers to the object bound to the method. If we create a principal variable: decrement d = new decrement (obj. function); where obj is an object, and function is a member function of obj. After it is finished, target refers to the OBJ object, and method refers to fun. Ction function.
Now that we know the true face of the decrement delegate, let's analyze the process from creating the delegate variable to calling the delegate method.
Complete delegated application instance
1 Using System;
2 Using System. Threading; // Namespace for thread operations (new)
3 Namespace Leleapplication3
4 {
5 Delegate Int Decrement ( Int X, Int Y ); // Define Delegation
6 Class Program
7 {
8 Static Void Main ( String [] ARGs)
9 {
10
11 Decrement mydelegate = New Decrement (function ); // Create a delegate variable. The parameter is function.
12 Int Result = Mydelegate ( 10 , 8 ); // Call
13
14 Console. Readline ();
15 }
16
17 Static Int Function ( Int X, Int Y)
18 {
19
20 Return X - Y;
21 }
22
23 }
24 }
The above is a simple but common method of delegation. Let's analyze the process below:
1) The first step is to define a delegate:Delegate IntDecrement (IntX,IntY );The compiler defines a class for us:Sealed ClassDecrement: multicastdelegate;
2) in step 2, we create a delegate variable: decrement mydelegate=NewDecrement (function); It is equivalent to defining a decrement Class Object. At the same time, it calls its constructor and assigns the function to the method member. The target is null. Of course, if we pass an instance method to the constructor, the parameter decrement mydelegate = new decrement (obj. function), then the target is OBJ;
3) Step 3: Use the delegate variable after it is created: int result = mydelegate (). In fact, when we write this sentenceCodeMydelegate is actually called. invoke () is a member function. This method is synchronous and congested. That is, the method returns the result of function execution only after the function method is executed.
Okay, three steps are right. What we want to study is how the invoke method blocks it !!
In order to better analyze this problem, we will slightly change the above delegated application instance:
Delegated application instance after modification
1 Using System;
2 Using System. Threading; // Namespace for thread operations (new)
3 Namespace Leleapplication3
4 {
5 Delegate Int Decrement ( Int X, Int Y ); // Define Delegation
6 Class Program
7 {
8 Static Void Main ( String [] ARGs)
9 {
10 Console. Write ( " Thread ID of the main method: {0} \ n " , Thread. currentthread. managedthreadid ); // ID of the thread where the output main method is located, that is, the ID of the main thread (newly added)
11
12 Decrement mydelegate = New Decrement (function ); // Create a delegate variable. The parameter is function.
13 Int Result = Mydelegate ( 10 , 8 ); // Call
14
15 Console. Readline ();
16 }
17
18 Static Int Function ( Int X, Int Y)
19 {
20 Console. Write ( " Thread ID of the Function Method: {0} \ n " , Thread. currentthread. managedthreadid ); // ID of the thread where the output function method is located (newly added) // thread. Sleep (10000 );
21 Return X - Y;
22 }
23
24 }
25 }
On the basis of the original, We output the ID of the thread where the method is located and the ID of the thread where the function method is located respectively in the main method. After running, we will find that the two output IDs are equal, which indicates that, when the delegate method is called using mydelegate (), the system does not start a new thread for us to execute the function method. This is the call process of the synchronous delegate.