Visual Basic Concepts
Providing an Asynchronous Notification Event
One of the most interesting uses for out-of-process components is to provide asynchronous notifications to the client. That is, the client doesn’t remain blocked while the component executes a method — instead, it goes about its business while the component works on a task or watches for an occurrence of interest. The component’s notification arrives out of the blue, without any specific action on the part of the client.
The procedure in this topic sets up a simple asynchronous notification based on a common data processing problem: How do you know when the coffee is ready?
The demonstration assumes that you have a coffee maker with a serial interface (however, the demonstration will work even if you don’t). The Coffee component tests the serial port periodically to see if the coffee maker’s High bit is set, indicating that the coffee is ready.
Before you begin this procedure, make sure you’ve returned the Coffee project to design mode, as described at the end of "How Modal and Modeless Forms Behave Out of Process."
Note This topic is part of a series that walks you through creating a sample ActiveX EXE. It begins with the topic Creating an ActiveX EXE Component.
To set up an asynchronous notification event in the CoffeeMonitor class
- In the Project Explorer window, right-click TestForm to open the context menu, and select View Object to open the form designer. Add a Timer control, and set its properties as follows:
Object | Property | Setting |
Timer control | (Name) Enabled Interval |
tmrCoffee True 10000 |
In the Project Explorer window, double-click CoffeeMonitor (or select it and then click the Code button on the Project Explorer window toolbar), to open its code window. Highlight all of the code except Option Explicit, and comment it out using the Comment Block button on the Edit toolbar, as shown here:
In order to view all the code at once, make sure you’ve selected Full Module View, as shown by the buttons in the lower left-hand corner of the code window.
You can show the Edit toolbar using the context menu accessed by right-clicking the menu or standard toolbar, as shown here:
In the Declarations section, add the following variables and event declaration:
Option Explicit Private mTestForm As TestForm Private WithEvents mwtmrCoffee As Timer Event CoffeeReady()
CoffeeMonitor will raise the CoffeeReady event to notify the CoffeeWatch program when the coffee’s ready.
The variable
mTestForm
will hold a reference to an instance of TestForm, whose only purpose is to hold the Timer control.The variable
mwtmrCoffee
will hold a reference to the Timer control on the TestForm. The variable is declared WithEvents so that the CoffeeMonitor object can handle the timer’s events.
In the left-hand (Object) drop down, select Class to make the event procedure templates for the class module available in the right-hand (Procedure) drop down, and to open the template for the default event (Initialize). Add the following code to create and load an instance of TestForm when the CoffeeMonitor object is created:
Private Sub Class_Initialize() Set mTestForm = New TestForm Load mTestForm Set mwtmrCoffee = mTestForm.tmrCoffee End Sub
After the instance of TestForm is created and loaded, a reference to
tmrCoffee
is placed in the variablemwtmrCoffee
. When the reference is placed in the WithEvents variable, Visual Basic connects the timer’s events to the associated event procedures in CoffeeMonitor.In the Procedure drop down, select the Terminate event for the class. Add the following code to the event procedure template:
Private Sub Class_Terminate() Set mwtmrCoffee = Nothing Unload mTestForm Set mTestForm = Nothing End Sub
As we saw in "How Modal and Modeless Forms Behave Out of Process," objects that use forms in out-of-process components need to dispose of the forms when they’re done with them. The first step is to set the WithEvents variable to Nothing, so that CoffeeMonitor will stop handling the Timer control’s events. Then TestForm can be unloaded, and the variable containing the reference to it can be set to Nothing.
Note Strictly speaking, there’s no need to set
mTestForm
to Nothing here. Visual Basic will set the variable to Nothing when it destroys the CoffeeMonitor object.In the Object drop down, select mwtmrCoffee. The Timer control’s only event, Timer, appears in the Procedure drop down, and the event procedure template is added to the code window. Add the following code:
Private Sub mwtmrCoffee_Timer() ' (Code to test serial port omitted.) RaiseEvent CoffeeReady End Sub
Event procedures associated with a WithEvents variable always begin with the variable name, as discussed in "Adding Events to Classes" in "General Principles of Component Design."
When the CoffeeMonitor object receives the Timer event, it raises its own CoffeeReady event to notify any clients (CoffeeWatch, in this case) that the coffee’s ready.
(This code simply raises the CoffeeReady event every ten seconds. If you actually have a coffee pot with a serial port, you can add code to test coffee maker’s status, and conditionally raise the event.)
Note One of the advantages of using events to provide notifications is that only one reference is needed. That is, TestForm doesn’t need a reference to the CoffeeMonitor object in order for the Timer control to send CoffeeMonitor an event. This avoids the circular reference problem described in "Dealing with Circular References" in "General Principles of Component Design."
Press CTRL+F5 to run the project. Remember, when working with out-of-process components, the component project must be in run mode before you can edit or run the client project.
Component projects should be run with CTRL+F5 (or Start with Full Compile on the Run menu) if Compile On Demand is checked, as discussed in "Showing Forms from the CoffeeMonitor Class."
For More Information* Events are introduced in "Adding an Event to a Class" and "Adding Events to Forms," in "Programming with Objects" in the *Visual Basic Programmer’s Guide.
Step by Step
This topic is part of a series that walks you through creating a sample ActiveX EXE.
To | See |
Go to the next step | Receiving an Asynchronous Notification Event |
Start from the beginning | Creating an ActiveX EXE Component |