Use a proxy in C # To trigger events (delegation and events)

Source: Internet
Author: User
From: http://www.cnblogs.com/gzhnan/articles/1859477.html

 

Use a proxy in C # To trigger events (delegation and events)

Event is a very important concept.ProgramVarious events are triggered and received at all times: mouse click events, keyboard events, and various operating system events. A thing is a message sent from an object. For example, if a user presses a button and a file changes, data on the socket reaches. The object that triggers an event is called the sender. The object that captures the event and responds to the event is called the receiver. An event can have multiple recipients.

In the asynchronous mechanism, events are an uncommon way of communication between threads. For example, you can click a button on the interface to execute a time-consuming task. The program starts a thread to process this task. a progress bar is displayed on the user interface to indicate the execution status of the user task. This function can be used to process events. The class that processes the task can be used as the message sender. When the task starts, the "taskstart" event is issued, and the "taskdoing" event is issued at different times during the task, parameters are included to describe the proportion of tasks. When the task ends, a "taskdone" event is sent to receive and process these events on the screen. In this way, the function is implemented, and the module coupling between the interface and the backend is also the lowest.

Specifically speaking, C # language, the implementation of events depends on the concept of "proxy" (delegate). First, let's take a look at proxy.

Proxy (delegate)

Delegate is a type in C #. It is actually a class that can hold a reference to a method. Unlike other classes, the delegate class can have a signature and can only hold references to methods that match its signature. Its functions are very similar to function pointers in C/C ++. It allows you to pass the method M of Class A to the object of Class B, so that the object of Class B can call this method M. But compared with function pointers, delegate has many advantages that function pointers do not possess. First, the function pointer can only point to static functions, while delegate can reference both static functions and non-static member functions. When referencing a non-static member function, delegate not only saves the reference to this function entry pointer, but also saves the reference to the class instance that calls this function. Second, compared with function pointers, delegate is an object-oriented, secure, and reliable managed object. That is to say, the runtime can ensure that the delegate points to a valid method. You do not need to worry that the delegate will point to an invalid or out-of-bounds address.

It is easy to implement a delegate. You can use the following three steps to implement a delegate:

1. Declare a delegate object. It should have the same parameter and return value type as the method you want to pass.

2. Create a delegate object and pass in the functions you want to pass as parameters.

3. Use the object created in the previous step to call the method where an asynchronous call is to be implemented.

The following is a simple example:

Public class mydelegatetest

{

// Step 1: declare the delegate object

Public Delegate void mydelegate (string name );

// This is the method we want to pass. It has the same parameter and return value type as mydelegate.

Public static void mydelegatefunc (string name)

{

Console. writeline ("Hello, {0}", name );

}

Public static void main ()

{

// Step 2: Create a delegate object

Mydelegate MD = new mydelegate (mydelegatetest. mydelegatefunc );

// Step 3: Call delegate

MD ("sam1111 ");

}

}

Output result: Hello, sam1111

Let's take a look at how the event is handled:

In C # Processing events

 

In C #, event processing is actually a delegate with a special signature, as shown below:

 

Public Delegate void myeventhandler (Object sender, myeventargs E );

 

The two parameters, sender represents the event sender, and E is the event parameter class. The myeventargs class is used to contain event-related data. All event parameter classes must be derived from the system. eventargs class. Of course, if your event does not contain parameters, you can directly use the system. eventargs class as the parameter.

 

With the implementation of Delegate, We can summarize the implementation of custom events into the following steps:

 

1. Defines the delegate object type. It has two parameters. The first parameter is the event sender object, and the second parameter is the event parameter class object.

 

2. Defines the event parameter class, which should be derived from the system. eventargs class. This step can be omitted if the event does not contain parameters.

 

3. Defines the event processing method. It should have the same parameter and return value type as the delegate object.

 

4. Use the event keyword to define the event object, which is also a delegate object.

 

5. Use the + = Operator to add events to the event queue (the-= operator can delete events from the queue ).

 

6. Call the delegate method to write the event trigger method where an event needs to be triggered. In general, this method should be a protected access restriction. It cannot be called in public mode, but can be inherited by the quilt class. The name is oneventname.

 

7. Call the event trigger method to trigger the event where appropriate.

 

The following is a simple example:

 

 

Using system;

 

 

Public class eventtest

 

{

 

// Step 1, define the delegate object

 

Public Delegate void myeventhandler (Object sender, system. eventargs E );

 

// Skip step 2

 

Public class myeventcls

 

{

 

// Step 3: Define the event processing method. It has the same parameters and return value type as the delegate object. //

 

Public void myeventfunc (Object sender, system. eventargs E)

 

{

 

Console. writeline ("My event is OK! ");

 

}

 

}

 

// Step 4: Use the event keyword to define the event object

 

Private event myeventhandler myevent;

 

 

Private myeventcls myecls;

 

 

Public eventtest ()

 

{

 

Myecls = new myeventcls ();

 

// Step 5: add the event to the queue with the + = Operator

 

This. myevent + = new myeventhandler (myecls. myeventfunc );

 

}

 

// Step 6: Write the event trigger function by calling delegate

 

Protected void onmyevent (system. eventargs E)

 

{

 

If (myevent! = NULL)

 

Myevent (this, e );

 

}

 

 

Public void raiseevent ()

 

{

 

Eventargs E = new eventargs ();

 

// Step 7: trigger the event

 

Onmyevent (E );

 

}

 

 

Public static void main ()

 

{

 

Eventtest ET = new eventtest ();

 

Console. Write ("Please input 'A ':");

 

String S = console. Readline ();

 

If (S = "")

 

{

 

Et. raiseevent ();

 

}

 

Else

 

{

 

Console. writeline ("error ");

 

}

 

}

 

}

 

 

The output result is as follows:

 

Please input 'A ': A

 

My event is OK!

//////////////////////////////////////// //////////////////////////////////////// //////////////////////////////////////// /////////////////


C # indicates the metadata and event triggering

The representative element is a complex concept in C, the representative element in C # is very similar to the function pointer in C/C ++. Using the representative element, You can encapsulate the reference representing the internal method of the element and use the method representing the metadata reference.
It has a feature that does not need to know that the referenced method belongs to that class object, as long as the number of parameters of the function is consistent with the return type and the Representative meta object. In this case, it may be abstract. I will give a few simple examples below, hoping to give the majority of beginners some basic knowledge.

// Define a non-Parameter Representation of the element whose return value is string. Note that this element can only reference the non-parameter method whose return value is string.
Delegate string mydelegate ();
Public class myclass
{
Public String sayhello ()
{
Return "Hello the world! ";
}

}
Public class testmyclass
{
Public static void main (string [] ARGs)
{
Myclass myclass1 = new myclass ();
Mydelegate mydelegate1 = new mydelegate (myclass1.sayhello );
// The following uses mydelegate1 to replace the sayhello method of the object myclass1.
System. Console. writeline (mydelegate1 ());
// The output result is Hello the world! The same effect as calling myclass1.sayhello ();
}
}
If the metadata only has this function, it will be of little use, another very useful function of representing Meta is to define a composite representing meta object. Only representative elements of the same type can be composite. + A composite representing meta object can be defined.-Remove a representative element from a composite element. object
Delegate void mydelegate (string S );
Public class myclass
{
Public void sayhello (string who)
{
System. Console. writeline (who + "Hello! ");
}
Public void saygoodbye (string who)
{
System. Console. writeline (who + "good bye! ");
}

}

Public class testmyclass
{
Public static void main (string [] ARGs)
{
Myclass myclass1 = new myclass ();
Mydelegate, mydelegate1;
Mydelegate = new mydelegate (myclass1.sayhello );
Mydelegate1 = new mydelegate (myclass1.saygoodbye );
Mydelegate + = mydelegate1;
// Calling mydeletage is equivalent to calling myclass1.sayhello and myclass1.saygoodbye at the same time.
Mydelegate ("love.net ");
// Output the execution result love.net hello! Love.net good bye!
}
}
Event-driven is an important feature of Windows applications. C # indicates that meta is used to generate events. Events are used to listen for changes to this component in a component.
The following is a simple example.
// Define an event proxy (representing the RMB)
Public Delegate void eventhandler (string Str );
// Define the event source class
Class eventsource
{
// Define the metadata as a member of the event source class
Public event eventhandler say;
Public void triggerevent ()
{
If (this. Say! = NULL)
// Because say is a metadata representative, the actual operations performed by executing the say method are determined by the event handler function registered with it.
Say ("A event take place! ");
}
}
// Test
Class Test
{
Public static void main ()
{
Eventsource aeventsource = new eventsource ();
// The register event handler function displays a string of characters similar to this. Click + = new eventhandler (button1_onclick) for myevent );
Aeventsource. Say + = new eventhandler (myevent );
// This shows the event trigger process, so it is automatically triggered by a program.
// In graphic interface applications, events are generally triggered by users, and then messages are sent by the operating system and processing functions are called. Therefore, programmers only need to register event processing functions.
// And compile the event processing function Code You don't need to worry about anything else.
Aeventsource. triggerevent ();
}
// Event processing functions
Public static void myevent (string Str)
{
System. Console. writeline (STR );
}

}

Analysis on Visual C # Event Processing Mechanism

Author: Wang kiming

Event introduction:

Any programmer who has performed graphic user interface development knows the concept of an event. When a user is using a program, the user must interact with the program. For example, when a user clicks a button on the form, the program will generate an event for the button to be clicked, and respond to the user's operations through the corresponding event processing function. In this way, the user's intuitive feeling is that the program executes the task I requested. Of course, events are not necessarily generated when they interact with users, and some events are generated inside the system and requested for processing. For example, a clock event is a good example. But to introduce the event processing mechanism in C # (the whole. NET Framework is extended to a wider scope), we must first understand the concept of "delegation.

Delegate in C:

Delegation, as the name implies, is the meaning of the intermediary agent. The delegate in C # allows you to pass the methods in an object to an object of another class that can call this method. You can pass a method M (included in a delegate) in Class A to Class B so that Class B can call the method M in Class. You can also pass this method in static or instance mode. Therefore, this concept is very similar to calling methods in other classes in the form of function pointers.

The concept of delegation was first proposed in Visual J ++. Now C # also applies the concept of delegation, which can be described as "ism. The delegate in C # is implemented by inheriting a class in system. Delegate. The specific steps are as follows:

1. Declare a delegate object. The parameter format must be consistent with the parameter form of the method you want to include.

2. define all the methods you want to define. The parameter format must be the same as that of the delegate object declared in step 1.

3. Create a delegate object and include the desired method in the delegate object.

4. Call the methods contained in the delegate object.

The following C # code shows how to use the above four steps to implement the delegation mechanism:

Using system;
File: // Step 1: declare a delegate object
Public Delegate void mydelegate (string input );

File: // Step 2: define each method. The parameter format must be the same as that of the delegate object declared in step 1.
Class myclass1 {
Public void delegatemethod1 (string input ){
Console. writeline (
"This is delegatemethod1 and the input to the method is {0 }",
Input );
}
Public void delegatemethod2 (string input ){
Console. writeline (
"This is delegatemethod2 and the input to the method is {0 }",
Input );
}
}

File: // Step 3: Create a delegate object and include the preceding Method
Class myclass2 {
Public mydelegate createdelegate (){
Myclass1 C2 = new myclass1 ();
Mydelegate d1 = new mydelegate (c2.delegatemethod1 );
Mydelegate D2 = new mydelegate (c2.delegatemethod2 );
Mydelegate D3 = D1 + D2;
Return D3;
}
}

File: // Step 4: Call the methods contained in the delegate object
Class myclass3 {
Public void calldelegate (mydelegate D, string input ){
D (input );
}
}
Class driver {
Static void main (string [] ARGs ){
Myclass2 C2 = new myclass2 ();
Mydelegate d = c2.createdelegate ();
Myclass3 C3 = new myclass3 ();
C3.calldelegate (d, "calling the delegate ");
}
}

C # event handler:

The event handler function in C # Is a delegate object with specific parameters in the form of the following:

Public Delegate void myeventhandler (Object sender, myeventargs E );

The first parameter (sender) specifies the object that triggers the event, and the second parameter (e) contains some data that can be used in the event processing function. The above myeventargs class is inherited from the eventargs class, which is a more widely used class, such as the base class of mouseeventargs class and listchangedeventargs class. For GUI-based events, you can use these more extensive and defined class objects for processing. For non-Gui-based events, you must derive your own class from the eventargs class and pass the data to the delegate object. The following is a simple example:

Public class myeventargs eventargs {
Public String m_myeventargumentdata;
}

In event processing functions, you can use the event keyword to reference the delegate object. The method is as follows:

Public event myeventhandler myevent;

Now let's create two classes. Through these two classes, we can know how the C # event processing mechanism works. In our instance, Class A provides the event processing function, and creates a delegate object in step 3 to include the event processing function at the same time, as described above, the parameter format of the event processing function must be the same as that of the delegate object. Class A then passes the delegate object to Class B. When an event in Class B is triggered, the event processing function in Class A is called accordingly. The following is the sample code:

Using system;
File: // Step 1: declare the delegate object
Public Delegate void myhandler1 (Object sender, myeventargs E );
Public Delegate void myhandler2 (Object sender, myeventargs E );

File: // Step 2: Create an event handler
Class {
Public const string m_id = "Class ";
Public void onhandler1 (Object sender, myeventargs e ){
Console. writeline ("I am in onhandler1 and myeventargs is {0 }",
E. m_id );
}
Public void onhandler2 (Object sender, myeventargs e ){
Console. writeline ("I am in onhandler2 and myeventargs is {0 }",
E. m_id );
}

File: // Step 3: Create a delegate object, and the event processing function contains the object in which the event is to be triggered.
Public A (B ){
Myhandler1 d1 = new myhandler1 (onhandler1 );
Myhandler2 D2 = new myhandler2 (onhandler2 );
B. event1 + = D1;
B. event2 + = d2;
}
}

File: // Step 4: Call the included method through the delegate object (that is, the trigger event)
Class B {
Public event myhandler1 event1;
Public event myhandler2 event2;
Public void fireevent1 (myeventargs e ){
If (event1! = NULL ){
Event1 (this, e );
}
}
Public void fireevent2 (myeventargs e ){
If (event2! = NULL ){
Event2 (this, e );
}
}
}
Public class myeventargs eventargs {
Public String m_id;
}
Public class driver {
Public static void main (){
B = new B ();
A A = new A (B );
Myeventargs e1 = new myeventargs ();
Myeventargs e2 = new myeventargs ();
E1.m _ id = "event ARGs for event 1 ";
E2.m _ id = "event ARGs for event 2 ";
B. fireevent1 (E1 );
B. fireevent2 (E2 );
}
}

The GUI event handler function in C:

There is no big difference between the basic method of completing the event processing function in GUI and the method described above. Next we will use the above method to complete a simple instance program. The main class of the Instance program, myform class, is inherited from Form class. By observing the entire code segment and related annotations, you can find that the delegate object is not declared for it and the delegate object is referenced by the event keyword, that's because the GUI control has already helped us do this job, and its delegate object is system. eventhandler. However, we still need to define methods for each control (that is, the event handler) and include them in the created delegate object (system. eventhandler. In this way, when the user interacts with the program, the corresponding event processing function will be triggered. The Code is as follows:
Using system;
Using system. drawing;
Using system. collections;
Using system. componentmodel;
Using system. Windows. forms;
Using system. Data;

Public class myform FORM {
Private button m_namebutton;
Private button m_clearbutton;
Private Label m_namelabel;

Private container m_components = NULL;

Public myform (){
Initializecomponents ();
}
Private void initializecomponents (){
M_namelabel = new label ();
M_namebutton = new button ();
M_clearbutton = new button ();

Suspendlayout ();

M_namelabel.location = new point (16, 16 );
M_namelabel.text = "Click name button, please ";
M_namelabel.size = new size (, 23 );

M_namebutton.location = new point (16,120 );
M_namebutton.size = new size (176, 23 );
M_namebutton.text = "name ";
File: // create a delegate object, including methods, and assign the delegate object to the button's Click Event
M_namebutton.click + = new system. eventhandler (namebuttonclicked );

M_clearbutton.location = new point (16,152 );
M_clearbutton.size = new size (176,23 );
M_clearbutton.text = "clear ";
File: // create a delegate object, including methods, and assign the delegate object to the button's Click Event
M_clearbutton.click + = new system. eventhandler (clearbuttonclicked );

This. clientsize = new size (292,271 );
This. Controls. addrange (new control [] {m_namelabel,
M_namebutton,
M_clearbutton });
This. resumelayout (false );
}
File: // define a method (event handler). The parameter format must be the same as that of the delegate object.
Private void namebuttonclicked (Object sender, eventargs e ){
M_namelabel.text =
"My name is John, please Click Clear button to clear it ";
}
Private void clearbuttonclicked (Object sender, eventargs e ){
M_namelabel.text = "Click name button, please ";
}
Public static void main (){
Application. Run (New myform ());
}
}

Summary:

In this way, I will give you a preliminary introduction to the Event Processing Mechanism in C. Through this article, we hope that you can handle the events in C # and even the whole process. net Framework has a general understanding of the event processing mechanism, but also hope that you can clearly define a new concept such as "delegate. Finally, if you are using the integrated development environment of Visual Studio for development, then the various GUI controls will automatically help you generate a lot of relevant code, but knowing its internal working mechanism is always of great benefit, right?

 

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.