Event, the word "event" often seems a bit mysterious and difficult to understand for beginners. But these things are often commonly used and very important things in programming. Everyone knows the importance of the Windows message processing mechanism. In fact, C# events are based on the Windows message processing mechanism, but they are better encapsulated, allowing developers to develop powerful event-based applications without knowing the underlying message processing mechanism.
Let’s first look at the benefits of event programming.
In the past, when we wrote such programs, we often used a waiting mechanism. In order to wait for something to happen, we needed to constantly detect certain judgment variables. After introducing event programming, this process was greatly simplified:
- Using events, it is easy to determine the order of program execution.
- When the event driver waits for an event, it does not take up a lot of resources. The biggest difference between event drivers and procedural programs is that the program no longer constantly checks the input device, but stays still, waiting for the message to arrive, and each input message will be queued and waits for the program to process it. If no message is waiting, the program will hand over control to the operating system to run other programs.
- Events simplify programming. The operating system simply passes messages to the object, and the object's event driver determines the handling method of events. The operating system does not have to know the internal working mechanism of the program, but only needs to know how to talk to the object, that is, how to pass messages.
With so many benefits, it seems that we do have to master it. As the saying goes, "If it is difficult, it won't be difficult, it won't be difficult." Let's start step by step...
To talk about events, we must talk about delegate. The relationship between them can be explained by a simple example, which may not be very appropriate. For example, if you want to rent a house, it is an incident. Then the entrustment is a house rental agency. When you inform the agency of renting a house, the agency will produce a house rental plan that meets your requirements. The agent then implements this plan and you can rent the house, that is, the incident is handled. Of course, you can also directly look for landlords without the agency, but if there are no tools such as the Internet, how do you get information about who rents a house? The topic is far from the bottom of the question.
Delegate
Delegates can be understood as function pointers, the difference is that delegates are object-oriented and type-safe. For understanding of commissions, please refer to another article in my article "Personal Understanding of C# Commissions".
Event
We can simply divide event programming into two parts: the class where the event occurs (called event generator in writing) and the class where the event receives and processes. The class where the event occurs means that an event is triggered in this class, but this class does not know which object or method will add and process the event it triggers. What is needed is a medium between the sender and the receiver. This medium is delegate in the .NET Framework. In the event receiving and processing class, we need to have a method to handle events. OK, we will implement a program that captures keyboard keys in this order, and explain step by step how to write event applications.
1. First create your own EventArgs class.
Quote from MSDN:
EventArgs is the base class of a class containing event data. This class does not contain event data. Events that do not pass status information to the event handler when an event is raised will use this class. If the event handler requires status information, the application must derive a class from this class to save the data.
Because our keyboard key event contains key information, we need to derive a KeyEventArgs class to save the key information so that later we know which key was pressed.
internal class KeyEventArgs : EventArgs { private char keychar; public KeyEventArgs( char keychar ) : base() { = keychar; public char Keychar { get { return keychar; } } }
2. Create another class KeyInputMonitor where the event occurs. This class is used to monitor the input of keyboard keys and trigger an event:
internal class KeyInputMonitor { // Create a delegate, return type void, and two parameters public delegate void KeyDownHandler( object sender, KeyEventArgs e ); // Associate the created delegate with a specific event, where the specific event is KeyDown public void Run() { bool finished = false; do { ( "Input a char" ); string response = (); char responsechar = ( response == "" ) ? ' ' : ( response[0] ); switch( responsechar ) { case 'X': finished = true; break; default: // Get the parameters for the button information KeyEventArgs keyEventArgs = new KeyEventArgs( responsechar ); // Trigger event KeyDown( this, keyEventArgs ); break; } } while( !finished ); } }
Pay attention to the KeyDown( this, KeyEventArgs ); here, this is the statement that triggers the event, and the event is handed over to the KeyDownHandler delegation to handle it, and the delegate to specify the event processing method to handle the event. This is the class of the event receiver. The parameter this refers to the object that triggers the event, which is the object itself, and keyEventArgs contains keypress information.
3. Finally, create a class that receives the event. This class first generates a delegate instance, and then adds this delegate instance to the event list that generates the event object. This process is also called subscription events. Then provide a method to echo the key information.
internal class EventReceiver { public EventReceiver( KeyInputMonitor monitor ) { // Generate a delegate instance and add it to the event list generated by KeyInputMonitor += new ( ); } private void OnKeyDown(object sender, KeyEventArgs e) { // Real event handling function ( "Capture key: {0}", ); } }
4. See how to call it
public class MainEntryPoint { public static void Start() { // Instantiate an event sender KeyInputMonitor monitor = new KeyInputMonitor(); // Instantiate an event receiver EventReceiver eventReceiver = new EventReceiver( monitor ); // Run (); } }
Summarize:
Steps required to use events in C#:
1. Create a delegate
2. Associate the created delegate with a specific event (many events in the .Net class library have been customized, so they have a corresponding delegate. When writing the associated event handler - that is, when an event occurs, we need to have the same signature as the delegate when the method we want to execute when an event occurs)
3. Write event handlers
4. Use the written event handler to generate a delegate instance
5. Add this delegate instance to the event list that generates the event object. This process is also called subscription event
The process of event generation and implementation in C#:
1. Define A as an instance that generates an event, a is an event generated by A
2. Define B as an instance of receiving an event and b as a method of processing an event
Because the user (program writer or program user) or the system generates an a event (for example, clicking a Button, generates a Click event)
Notify B of this event through the delegate object in the event list
Received an event notification (actually using delegate to achieve event reception)
6. Calling the method to complete the event processing
public class A { public delegate void EventHandler(object sender); public void Run() { ("Trigger an event."); a(this); } } class B { public B(A a) { += new (); } private void b(object sender) { ("Received and handled an event." ); (); } }