VB.NET中SystemEvents的Handles声明和AddHandler之间的区别

时间:2014-08-25 14:59:52

标签: .net vb.net events addhandler

我正在使用设备驱动程序,我需要在系统进入休眠状态时关闭它。我以为我可以将SystemEvents.PowerModeChanged事件的处理程序添加到ApplicationEvents.vb,如下所示:

Public Sub SystemEvents_PowerModeChanged(sender As Object, e As PowerModeChangedEventArgs) _
        Handles SystemEvents.PowerModeChanged

    If e.Mode = PowerModes.Suspend Then
        logger.Trace("The computer is suspending. Closing device.")
        'Close device
    ElseIf e.Mode = PowerModes.Resume Then
        logger.Trace("The computer is resuming operation from suspend mode. Opening device.")
        ' Open device
    End If
End Sub

使用Handles关键字处理事件。但是,Handles子句中存在编译错误:

Handles clause requires a WithEvents variable defined in the containing type or one of its base types.

WithEvents似乎总是为我在.NET中遇到的其他事件定义,那么为什么这个不同呢?我更喜欢使用Handles子句,因为这会自动添加和删除处理程序。它还保持功能自包含,而不是在初始化程序,析构函数和函数本身之间传播。是否可以在此事件中使用句柄声明?

此问题的一个线索是以下代码可以正常工作:

AddHandler SystemEvents.PowerModeChanged, AddressOf SystemEvents_PowerModeChanged

1 个答案:

答案 0 :(得分:3)

SystemEvents类的事件与您习惯的类型不同,它们是静态事件。 "共享"在vb.net中说话。你可以通过意识到只有一个"系统"来证明这一点。所以只有一个事件来源。

这使得关于WithEvents的MSDN文章中的这篇文章相关:

  

您必须将WithEvents变量声明为对象变量,以便它们可以接受类实例。

您无法创建SystemEvents类型的对象变量。因此,您无法使用WithEvents关键字。所以你也不能使用Handles子句。回到AddHandler是一项艰巨的要求。

而且,非常重要的是,当您不再对此事件感兴趣时,您必须明确使用RemoveHandler。例如在Form的FormClosed事件处理程序中。必要时,当您的UI不再存在时,SystemEvents会停止触发您的事件处理程序。忘记这样做会导致内存泄漏(表单对象不能被垃圾回收),如果你很幸运,则会出现ObjectDisposedException。如果关闭表单或窗口也会终止您的应用,则只能跳过此要求。