我正在使用设备驱动程序,我需要在系统进入休眠状态时关闭它。我以为我可以将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
答案 0 :(得分:3)
SystemEvents类的事件与您习惯的类型不同,它们是静态事件。 "共享"在vb.net中说话。你可以通过意识到只有一个"系统"来证明这一点。所以只有一个事件来源。
这使得关于WithEvents的MSDN文章中的这篇文章相关:
您必须将WithEvents变量声明为对象变量,以便它们可以接受类实例。
您无法创建SystemEvents类型的对象变量。因此,您无法使用WithEvents关键字。所以你也不能使用Handles子句。回到AddHandler
是一项艰巨的要求。
而且,非常重要的是,当您不再对此事件感兴趣时,您必须明确使用RemoveHandler
。例如在Form的FormClosed事件处理程序中。必要时,当您的UI不再存在时,SystemEvents会停止触发您的事件处理程序。忘记这样做会导致内存泄漏(表单对象不能被垃圾回收),如果你很幸运,则会出现ObjectDisposedException。如果关闭表单或窗口也会终止您的应用,则只能跳过此要求。