Use .NET to program events

xiaoxiao2021-03-06  66

Author: Ted Pattison

You may have already programmed a number of years, but migrate to .NET Framework still requires you to retrieve the internal work of the event, because the event in .NET Framework is located on the top floor of the delegated. The more you know the entrustment, the stronger the ability to program the event. When you start using an event-driven framework (such as Windows® Forms or ASP.NET), it is important to understand how to work at a lower level. My goal this month is how to understand how the event works at a lower level. What is an event? The event is a formal software mode in which the notification source will call one or more handler methods. Therefore, events are similar to interfaces and delegates because they provide methods for designing applications using callback methods. However, events greatly improve work efficiency because they are easier than interfaces or commission. Event allows compilers and Visual Studio® .NET IDE to do a lot of work for you behind the scenes. Design of events is based on event source and one or more event handler. The event source can be a class or an object. The event handler is a delegate object that is bound to the handler method. Figure 1 shows a high level view of the event source that is bound to its handler method.

Figure 1 Event source and handler

Each event is defined according to a particular delegate type. For each event defined by the event source, there is a private field based on an event-based basic commission type. This field is used to track multiple broadcast delegate objects. The event source also provides a public registration method that allows you to register the number of event handlers. When you create an event handler (delegate object) and register it in the event source, the event source is just appended from the new event handler to the end of the list. Then, the event source can use the private field to call Invoke on the multi-broadcast commission, the multi-channel broadcast commission will execute all registered event handler sequentially. The true task of an event is that a lot of work set is ready for you. As you will soon see, no matter where you define an event, Visual Basic® .NET compiler will help you work by automatically adding private commission fields and public registration methods. You will also see that Visual Studio .NET can provide more help through the code generator, the code generator automatically issues the main definition for your handler method. Programming events Due to the top-level entrusted in .NET, their basic pipe details are completely different from the lower version of Visual Basic. However, Visual Basic .NET language designers are doing well in consensus on the syntax of the event programming and the lower version of Visual Basic. In many cases, the syntax of the event is the same as the familiar old grammar for your habits. For example, you will use keywords such as Event, RaiseEvent and WitHhevents, and their behavior is almost identical to their behavior in lower versions of Visual Basic. Let us start by creating an event-based simple callback design. First, I need to define an event within the class definition by using the Event keyword. Each event must be defined based on a particular commission type. Below is an example of defining a custom delegate type and a class for defining events: Delegate Sub LargewithdrawHandler (Byval Amount As Decimal)

Class BankAccount

Public Event Largewithdraw As LargewithDrawhandler

'*** other members omitted

END CLASS

In this example, the LARGEWITHDRAW event is defined as an instance member. In this design, the BankAccount object will act as an event source. If you want the class rather than the object to act as an event source, you should use the Shared keyword to define the event as a shared member. When programming the event, you know that the compiler has made a lot of extra work for you after the scene. For example, when you compile the definition of the BankAccount class I have seen to you, what do you think of the compiler will do? Figure 2 shows what is the definition when checking the generated class definition in the intermediate language disassembler iLDasm.exe. This view does not reserve a Visual Basic .NET compiler how much work has been made to help you. Figure 2 Class definition in iLDASM

When you define an event, the compiler generates four members in the class definition. The first member is a private field based on the principal type. This field is used to track references to the delegate object. The compiler generates the name of the private field by using the name of the event itself and adds a suffix "event". This means that events that create named LARGEWITHDRAW will result in a private field named LARGEWITHDRAWEVENT. The compiler also generates two methods to help registration and logout will become a delegate object for the event handler. These two methods are named using standard naming rules. The method for registering the event handler uses the name of the event and has the prefix "Add_". The method for logging out the event handler uses the name of the event and has a prefix "remove_". Therefore, two methods created for the LARGEWITHDRAW event are add_largewithdraw and remove_ilanwithdraw. Visual Basic .NET compiler generates an implementation by calling the DELEGATE Class's COMBINE method to accept the delegate object as a parameter and add it to the add_largewithdraw in the handler list. The compiler generates an implementation by calling the REMOVE method in the Delegate class to remove a resove_largewithdraw from a handler method from the list. The fourth is also a member of the last addition to the class definition is a member representing the event itself. In Figure 2, you should be able to find event members named LARGEWITHDRAW. It is a member with a fall triangle next to it. However, you should be noted that this event is not just like a physical member as the other three members. Instead, it is a member containing only metadata. This event member only contains metadata is valuable because it can notify the compiler supported by the class and other development tools to register the standard mode in the event registration in the .NET Framework. The event member also contains the name of the registration method and the logout method. This makes the Visual Basic .NET and C #, the compiler of the hosted language, can look for the name of the registration method at compile. Visual Studio .NET is another good example of finding a development tool that only contains metadata event members. When the Visual Studio .NET discovery class definition When the event includes an event, it automatically generates the main definition of the processor method and the code that will be registered as an event handler. Before you start discussing the incident, I would like to propose a limit on the type of commissioned type for defining the event. The type of delegate used to define events cannot be returned. You must use the SUB keyword instead of the function keyword definition of the delegate type, as shown below: '*** can be used for Events

Delegate Sub BaggageHandler ()

Delegate Sub Mailhandler (ItemID AS Integer)

'*** Cannot Be Used for Events

Delegate Function QuoteoftHedayHandler (Funny As Boolean) AS String

There is a very reason for this limit. When the multi-broadcast commission that is bound to a number of handler methods, the processing return value is quite difficult. Calling Invoke on multiple broadcast commissioning to return the same value as the last handler method in the call list. However, the return value captured by the processing program method that appears earlier in the list is not that simple. You don't need to capture multiple return values ​​that will only make events easier. Inspire events now, let us modify the BankAccount class to inspire an event when the number of withdrawals exceeds a $ 5000 threshold. The easiest way to excite the LARGEWITHDRAW event is to use the RaiseEvent keyword in one method, attribute, or constructor. You may feel that this syntax is familiar because it is similar to the syntax you use in a lower version of Visual Basic. Here is an example of exciting the LargewithDraw event from the Withdraw method: Class BankAccountPublic Event LargewithDraw As LargewithDrawhandler

Sub withdraw (ByVal Amount As Decimal)

'*** Send Notifications IF Required

IF (Amount> 5000) THEN

RaiseEvent Largewithdraw (Amount)

END IF

'*** Perform withdrawal

End Sub

END CLASS

Although the syntax is the same as the lower version of Visual Basic, what happens when the incident occurs when it is now very different. When using the RaiseEvent keyword, the Visual Basic .NET compiler generates the code required to perform each event handler. For example, what happens when you compile the following code? RaiseEvent Largewithdraw (Amount)

The Visual Basic .NET compiler extends this expression to call the invoke code on the private field that retains multiple broadcast delegate objects. In other words, using the RaiseEvent keyword with identical effects in writing code in the following snippet: if (not LargewithdrawEvent is nothing "

LargewithdrawEvent.Invoke (Amount)

END IF

Note that the code generated by the Visual Basic .NET compiler performs an inspection to make sure the LARGEWITHDRAWEVENT field contains a valid reference to an object. This is because the value of the LARGEWITHDRAWEVENT field is always Nothing before the first handler method is registered. Therefore, unless there is at least one process program method has been registered, the generated code does not attempt to call Invoke. You should be able to observe the excitation event. Direct programming directly using the RaiseEvent keyword or the LARGEWITHDRAWEVENT private field automatically generated by the compiler is usually nothing. Both methods produce the same code: '*** this code

RaiseEvent Largewithdraw (Amount)

'*** is The Same as this code

IF (not LargewithdrawEvent Is Nothing) THEN

LargewithdrawEvent.Invoke (Amount)

END IF

In many cases, you may like to use the RaiseEvent keyword syntax because it needs to be typed, and the generated code is more concise. However, in some cases, when you need more control, it will make sense according to the LARGEWITHDRAWEVENT private field. Let us look at an example of this situation. Imagine the following: The BankAccount object has three event handlers that are registered to receive notifications for the LARGEWITHDRAW event. What happens if the event is used to trigger an event using the RaiseEvent keyword and the second event handler in the call list occurs. The code line containing the RaiseEvent statement will receive running exception, but you may have no way to determine which event handler causing an exception. Moreover, there may be no way to deal with the exception caused by the second event handler, and there is no way to continue on the position of the third event handler in the expected manner. However, if you are willing to program according to the LARGEWITHDRAWEVENT private field, you can process the exception caused by the event handler more. Check the code in Figure 3. As you can see, it is reduced to a lower level and programming an additional control based on the private delegate field. You can handle exceptions properly and then continue to perform event handlers in the list in the list. Compared to the RaiseEvent syntax, this method has a significant benefit, and an exception caused by an event handler in this method will prevent any event handler that appears late from the call list. Creating and Registering Event Handle Now, you know how to define and motivate events, which is discussed how to create an event handler and register it in a given source. There are two different ways to complete the above operations in Visual Basic .NET. The first method is called dynamic event binding, involving the use of the AddHandler keyword. The second method is called static event binding, involving familiar Visual Basic Keywords WitHevents. I plan to discuss static event bindings in the next issue. So now let us take a look at the working principle of dynamic event binding. Remember, the event handler is a delegate object. Therefore, an event handler can be created by instantifying a delegate object from the principal based type based on the event. When you create this delegate object, you must bind it to the target handler method to be an event handler. After creating an event handler, you must register it in a specific event by calling a specific registration method on the event source. Memolive, the registration method of the LARGEWITHDRAW event is named add_largewithdraw. When you call the add_ilawithdraw method and passes the delegate object as a parameter, the event source adds the delegate object to the list of event handler that will receive event notifications. The event registration will be confused that you never call Add_LarGewITHDRAW directly. In fact, if you access the event registration method by name, the Visual Basic .NET compiler will generate compile time errors. However, you can use an alternative syntax including the AddHandler statement. When you use the AddHandler statement, the Visual Basic .NET compiler has become the code for you call the event registration method. Let's take a look at an example of using dynamic event registration binding several event handlers. Imagine you have written a collection of sharing methods in the AccountHandlers class: Class AccountHandlersShared Sub LogwithDraw (Byval Amount As Decimal)

'*** Write Withdrawal Info to Log File

End Sub

Shared Sub GetApproval (Byval Amount As Decimal)

'*** Block Until Manager Approvalend Sub

END CLASS

What should you do if you want to use these methods as a LARGEWITHDRAW event for a BankAccount class? Let's start with the event handler that creates a binding to the handler LogwithDraw. First, you must create a delegate object that will become an event handler: DIM HANDLER1 AS LARGEWITHDRAWHANDLER

Handler1 = addressof accounthandlers.logwithdraw

You must then use the AddHandler statement to register the new delegate object in the event source. When you use the AddHandler statement to register an event handler, you need to pass two parameters. Similar to the following: addHandler ,

The first parameter required by AddHandler is an expression that evaluates the event of the class or object. The second parameter is a reference to the delegate object that will be bound to the event handler. Here is an example of registering an event handler in a LargewithDraw event using the AddHandler statement in the LargewithDraw event of the BankAccount object: '*** Create Bank Account Object

DIM Account1 as new bankaccount ()

'*** Create and Register Event Handler

Dim Handler1 As LargewithDrawhandler

Handler1 = addressof accounthandlers.logwithdraw

AddHandler Account1.Largewithdraw, Handler1

When you use the AddHandler Keyword to register the LARGEWITHDRAW event, the Visual Basic .NET compiler will extend this code to call the registration method add_largewithdraw. After executing the code containing the AddHandler statement, your event handler is in place and is ready to be notified. Therefore, the LogwithDraw method will be executed whenever the BankAccount object is excited by the BankAccount object. In the previous example, I use a long form of syntax to exactly what happened when creating and registering event handles. However, after understanding the principle, you may want to use a more concise syntax to achieve the same goal, as shown below: '*** Create Bank Account Object

DIM Account1 as new bankaccount ()

'*** Register Event Handlers

AddHandler Account1.Largewithdraw, Addressof AccountHandlers.logwithDraw

AddHandler Account1.Largewithdraw, Addressof AccountHandlers.GetApproval

Since the AddHandler statement is expected to reference the delegation object as the second parameter, you can use the ADDRESSOF operator's shorthand syntax, followed by the target method. When the Visual Basic .NET compiler found this, it generates additional code to create a delegate object that will become an event handler. The AddHandler statement of the Visual Basic .NET language is supplemented by the RemoveHandler statement. The two parameters required by RemoveHandler are the same as addHandler, but it has the opposite effect. It removes the target handler method from the registered handler list by calling the event source: DIM Account1 as new bankaccount () *** register Event Handler

AddHandler Account1.Largewithdraw, Addressof AccountHandlers.logwithDraw

'*** Unregister Event Handler

RemoveHandler Account1.LargewithDraw, Addressof AccountHandlers.logwithDraw

Now, you have seen all the steps needed to use events to implement callback design. The above code shows a complete application that is registered in two event handles in the application to receive a callback notification of the LargewithDraw event from the BankAccount object. Summary Although the motivation and certain grammar use of the events have not changed compared to lower versions of Visual Basic, you must admit that the current situation is different. As you can see, your ability to respond to events is stronger than before. This is even more like this if you want to lower the level and program it according to the delegate. In the next Basic Instincts column, I intend to continue the discussion of the event. I will show you how Visual Basic .NET supports static event binding through your familiar WitHevents keyword syntax, and will discuss the Handles clause. To really control events, you must easily manage dynamic event registration and static event registration.

转载请注明原文地址:https://www.9cbs.com/read-82209.html

New Post(0)