提供异步通知事件

为客户提供异步通知是进程外部件最有趣的用途之一,也就是,当部件执行方法时,客户没有保持阻塞状态,当部件执行某个任务上或等待某事发生时,客户继续做自己的事务。部件的通知突然来到时,在客户部分没有任何特殊的行动。

本主题中的过程建立了基于一般数据处理问题的简单异步通知:怎么知道咖啡什么时候准备好?

该演示假设有个带串行口的咖啡机器(即使没有的话,演示也同样工作)。Coffee 部件周期性地测试串行口,如果咖啡机器的高位被设置了,就说明咖啡好了。

在开始该过程之前,确认 Coffee 工程在设计状态,正如在“模式和无模式窗体在进程外如何运转”的末尾所讨论的那样。

注意 本主题是逐步创建 ActiveX EXE 示例过程中的一部分。选择“创建 ActiveX EXE 部件”,开始本主题。

要在 CoffeeMonitor 类中建立异步通知事件,请按照以下步骤执行:

  1. 在“工程资源管理器”窗口的“TestForm”上单击右键打开上下文菜单,并选择“查看对象”打开窗体设计器。添加 Timer 控件,并按如下所述设置它的属性:
    对象 属性 设置值
    Timer control (Name)
    Enabled
    Interval
    tmrCoffee
    True
    10000

    不必在 tmrControl_Timer 事件过程中放置代码。将会看到,CoffeeMonitor 会处理控件的 Timer 事件,测试串行口,并产生 CoffeeReady 事件来通知 CoffeeWatch。

  2. 在“工程资源管理器”窗口内,双击“CoffeeMonitor”(或选中它,然后单击“工程资源管理器”窗口工具栏上的“代码”按钮),打开代码窗口。突出显示除了 Option Explicit 以外的所有代码,并用“编辑”工具栏上的“设置注释块”按钮来进行注释,如下所示:

    为了立即看到所有的代码,确信选择了全模块视图,这由代码窗口左下脚的按钮显示。

    使用右键单击菜单或标准工具栏弹出的上下文菜单可以显示“编辑”工具栏,如下所示:

  3. 在声明部分添加下列变量和事件声明:
    Option Explicit
    Private mTestForm As TestForm
    Private WithEvents mwtmrCoffee As Timer
    Event CoffeeReady()
    
  4. 在左边的(对象)下拉菜单中,选择 Class 使类模块的事件过程模板出现在右边的(过程)下拉菜单中,并打开缺省事件 (Initialize) 的模板。当 CoffeeMonitor 对象被创建时,添加下列代码来创建并加载 TestForm 的实例:
    Private Sub Class_Initialize()
    Set mTestForm = New TestForm
    Load mTestForm
    Set mwtmrCoffee = mTestForm.tmrCoffee
    End Sub
    

    TestForm 的实例被创建和加载后,对 tmrCoffee 的引用放置在变量 mwtmrCoffee 中。当该引用被放置在 WithEvents 变量中时,Visual Basic 把计时器事件连接到 CoffeeMonitor 中的相关事件过程中。

  5. 在“过程”下拉菜单中,选中类的 Terminate 事件。把下列代码添加到事件过程模板中:
    Private Sub Class_Terminate()
    Set mwtmrCoffee = Nothing
    Unload mTestForm
    Set mTestForm = Nothing
    End Sub
    

    正如在“模式和无模式窗体在进程外如何运转”中曾看到过的那样,使用在进程外部件中的窗体的对象,在这些窗体用完后要把它们释放掉。第一步是把 WithEvents 变量置成 Nothing,使 CoffeeMonitor 停止处理 Timer 控件的事件,然后卸载 TestForm,同时把引用它的变量置成 Nothing。

    注意 严格说来,这里没必要把 mTestForm 置成 Nothing。Visual Basic 在破坏 CoffeeMonitor 对象时将把变量置成 Nothing。

  6. 在“对象”下拉菜单中,选择 mwtmrCoffee。Timer 控件的唯一事件“Timer”将出现在“过程”下拉菜单中,事件过程模板同时也被添加到代码窗口中。添加如下代码:
    Private Sub mwtmrCoffee_Timer()
    '(这里省略了测试串行口的代码。)
    RaiseEvent CoffeeReady
    End Sub
    

    与 WithEvents 变量相关的事件过程总是以该变量名开头,这一点在“部件设计的一般准则”的“给类添加事件”中讨论。

    当 CoffeeMonitor 对象收到 Timer 事件后,就产生它的 CoffeeReady 事件,通知所有客户(在这里是 CoffeeWatch)咖啡已准备好。

    (这些代码只是每隔十秒产生 CoffeeReady 事件。如果串行口上真的有咖啡壶,就可以添加代码测试咖啡壶的状态,有条件地产生事件)。

    注意 用事件来提供通知的好处之一是只需要一次引用。也就是,TestForm 不需要引用 CoffeeMonitor 对象来使 Timer 控件给 CoffeeMonitor 发送事件。这避免了“部件设计的一般准则”的“循环引用的处理”中描述的循环引用问题。

  7. 按 CTRL+F5 键运行工程。记住,当使用进程外部件时,在能够编辑或运行客户工程之前必须使部件工程处于运行状态。

    如从 CoffeeMonitor 类显示窗体所述,如果选中“请求时编译”,则应通过 CTRL+F5 (或“运行”菜单上的“启动全编译”)来运行部件工程。

详细信息 事件在《Visual Basic 程序员指南》的“用对象编程”中的“给类添加事件”和“给窗体添加事件”中介绍。

循序渐进

本主题是逐步创建 ActiveX EXE 示例的一系列过程中的一部分。

要到 请参阅
下一步 接收异步通知事件
从头开始 创建 ActiveX EXE 部件