1

我正在使用一个设备驱动程序,当系统进入睡眠状态时我需要关闭它。我想我可以将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 子句,因为这会自动添加和删除处理程序。它还保持功能自包含,而不是将其分布在初始化程序、析构函数和函数本身之间。是否可以在此事件上使用 Handles 声明?

这个问题的一个线索是以下代码确实有效:

AddHandler SystemEvents.PowerModeChanged, AddressOf SystemEvents_PowerModeChanged
4

1 回答 1

3

SystemEvents 类的事件与您习惯的不同,它们是静态事件。vb.net 中的“共享”发言。你可以通过意识到只有一个“系统”来推断这一点。因此,该事件只有一个来源。

这使得与 WithEvents 相关的 MSDN 文章中的此文本:

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

您不能创建 SystemEvents 类型的对象变量。所以你不能使用 WithEvents 关键字。所以你也不能使用 Handles 子句。回退到AddHandler是一个坚如磐石的要求。

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

于 2014-08-25T15:32:48.180 回答