gpt4 book ai didi

.NET 删除事件处理程序并销毁调用的事件

转载 作者:行者123 更新时间:2023-12-01 22:33:31 24 4
gpt4 key购买 nike

在我的应用程序的主窗体上,我有一个事件处理程序,它是从与 UI 不同的线程调用的,因为它是由硬件设备生成的事件。同步。对于 GUI 线程,当事件被调用时,我执行 Form.BeginInvoke()。然后该调用将在消息循环中排队。

当用户需要关闭表单时,在关闭之前我删除了事件的处理程序,但似乎仍然可以调用调用的调用。然后,如果处理事件的例程使用了一些在调用它时不再可用的信息,我可能会遇到问题。

例如:

Private MyDevice as New SomeDevice()
Private MyGlobalVar as MyVarType

Public Sub OnDeviceEvent()

If InvokeRequired Then
BeginInvoke(Sub() OnDeviceEvent())
Return
End If

If MyGlobalVar.Field = 0 then
'do something
end if

End Sub

Public Sub PrepareToCloseForm()

'removes the handler of the event
RemoveHandler MyDevice.DeviceEvent, AddressOf OnDeviceEvent

MyGlobalVar = Nothing

End Sub

使用上面的代码,在运行PrepareToCloseForm()之后,有时我会在以下行中收到对象空错误:

If MyGlobalVar.Field = 0 then

我可以在使用变量之前进行 Null 检查,但由于我有许多其他事件,我想要一个更优雅的解决方案。如何确保删除处理程序后不会发生 Invoked 调用?

在删除所有处理程序以处理待处理消息之前,我是否应该调用 DoEvents?

最佳答案

您遇到的问题是,如果您关闭该事物并将 MyGlobalVar 设置为 Nothing,即使 OnDeviceEvent 对此进行了检查,当您仍在尝试使用它时,它也可能随时变得什么都没有。为了解决这个问题,您可以在访问 MyGlobalVar 时放置一个 SyncLock

Private MyDevice as SomeDevice()
Private MyGlobalVar as MyVarType
Private SyncLockObject as New Object

Public Sub OnDeviceEvent()

If InvokeRequired Then
BeginInvoke(Sub() OnDeviceEvent())
Return
End If

SyncLock SyncLockObject
If MyGlobalVar IsNot Nothing Then
If MyGlobalVar.Field = 0 then
'do something
End If
End If
End SyncLock

End Sub

Public Sub PrepareToCloseForm()

'removes the handler of the event
RemoveHandler MyDevice.DeviceEvent, AddressOf OnDeviceEvent

SyncLock SyncLockObject
MyGlobalVar = Nothing
End SyncLock

End Sub

这样,当 OnDeviceEvent 正在访问 MyGlobalVar 时,您无法将其设置为空,并且当 PrepareToCloseForm 将其设置为 Nothing 时,OnDeviceEvent 无法访问它

关于.NET 删除事件处理程序并销毁调用的事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46961976/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com