Providing an Asynchronous Notification Event

See Also

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

  1. 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

    There’s no need to put code in the tmrControl_Timer event procedure. As you’ll see, CoffeeMonitor will handle the control’s Timer event, test the serial port, and raise the CoffeeReady event to notify CoffeeWatch.

  2. 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:

  3. In the Declarations section, add the following variables and event declaration:
    Option Explicit
    Private mTestForm As TestForm
    Private WithEvents mwtmrCoffee As Timer
    Event CoffeeReady()
    
  4. 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 variable mwtmrCoffee. When the reference is placed in the WithEvents variable, Visual Basic connects the timer’s events to the associated event procedures in CoffeeMonitor.

  5. 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.

  6. 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."

  7. 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