深入处理 VB.NET 事件

标签 vb.net winforms events event-handling

任何人都知道 VB.NET 中的事件是如何工作的 我特别怀疑的是,如果事件代码没有完成对事件的处理并且发生了新的事件,会发生什么。

即:我有 doubleClick 事件,并且用户非常快地重复且持续地双击很多次。

事件代码以相同的形式调用一些子例程和函数(不是多线程)

事件代码从顶部重新启动还是等到所有代码执行完后重新进入?

今天我发现以下两个错误

错误1:

Error al crear identificador de ventana.
en System.Windows.Forms.NativeWindow.CreateHandle(CreateParams cp)
en System.Windows.Forms.Control.CreateHandle()
en System.Windows.Forms.Control.CreateControl(Boolean fIgnoreVisible)
en System.Windows.Forms.Control.CreateControl()
en System.Windows.Forms.Control.ControlCollection.Add(Control value)
en System.Windows.Forms.TabControl.ControlCollection.Add(Control value)
en System.Windows.Forms.TabControl.TabPageCollection.Insert(Int32 index, TabPage tabPage)
en Commands.Form1.DataGridViewAlarms_CellMouseDoubleClick(Object sender, DataGridViewCellMouseEventArgs e)

错误2:

Error al crear identificador de ventana.
en System.Windows.Forms.NativeWindow.CreateHandle(CreateParams cp)
en System.Windows.Forms.Control.CreateHandle()
en System.Windows.Forms.Control.get_Handle()
en System.Windows.Forms.Control.CreateGraphicsInternal()
en System.Windows.Forms.ThreadExceptionDialog..ctor(Exception t)
en System.Windows.Forms.Application.ThreadContext.OnThreadException(Exception t)
en System.Windows.Forms.Control.WndProcException(Exception e)
en System.Windows.Forms.Control.ControlNativeWindow.OnThreadException(Exception e)
en System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
en System.Windows.Forms.UnsafeNativeMethods.IntCreateWindowEx(Int32 dwExStyle, String lpszClassName, String lpszWindowName, Int32 style, Int32 x, Int32 y, Int32 width, Int32 height, HandleRef hWndParent, HandleRef hMenu, HandleRef hInst, Object pvParam)
en System.Windows.Forms.UnsafeNativeMethods.CreateWindowEx(Int32 dwExStyle, String lpszClassName, String lpszWindowName, Int32 style, Int32 x, Int32 y, Int32 width, Int32 height, HandleRef hWndParent, HandleRef hMenu, HandleRef hInst, Object pvParam)
en System.Windows.Forms.NativeWindow.CreateHandle(CreateParams cp)
en System.Windows.Forms.Control.CreateHandle()
en System.Windows.Forms.TabControl.CreateHandle()
en System.Windows.Forms.Control.CreateControl(Boolean fIgnoreVisible)
en System.Windows.Forms.Control.CreateControl(Boolean fIgnoreVisible)
en System.Windows.Forms.Control.CreateControl(Boolean fIgnoreVisible)
en System.Windows.Forms.Control.CreateControl()
en System.Windows.Forms.Control.ControlCollection.Add(Control value)
en System.Windows.Forms.TabControl.ControlCollection.Add(Control value)
en System.Windows.Forms.TabControl.TabPageCollection.Insert(Int32 index, TabPage tabPage)
en Commands.Form1.DataGridViewAlarms_CellMouseDoubleClick(Object sender, DataGridViewCellMouseEventArgs e)

这个错误并不总是发生,我有大约 20 台机器使用相同的程序,只有一个用户遇到这个问题,并且当他快速重复双击时总是会发生。


我使用以下代码删除 TapPages

Dim CurrentTab As TabPage = AlarmsTabControl.SelectedTab
AlarmsTabControl.TabPages.Remove(CurrentTab)

最佳答案

WinForm 框架是单线程的。因此,所有事件都在单线程上处理。因此,当调用事件处理程序时,在第一个事件处理程序完成之前不会调用其他事件处理程序。换句话说,事件处理程序以串行方式调用。

事件处理程序可以被另一个事件中断的唯一方法是通过调用 Application.DoEvents 主动放弃控制。正如您可以想象的那样,调用 DoEvents 可能会导致意外行为。由于调用 DoEvents 通常会导致错误,因此它被广泛劝阻并被视为糟糕设计的标志。在这种情况下,通常表明使用 BackgroundWorker 更合适。

再深入一点

当从操作系统接收到窗口消息时,将触发与 UI 相关的事件。传入的窗口消息被添加到队列中。每个进程都有责任从队列中读取这些窗口消息并进行适当的处​​理。通常这是在 Message Loop 中完成的它按顺序处理队列中的每条消息,或者空闲直到收到新消息。每次消息循环找到要处理的新消息时,它都会调用 Window Procedure 。窗口过程通常称为WindowProcWndProc。在.NET WinForm项目中,消息循环是通过调用Application.Run启动的。

关于深入处理 VB.NET 事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21484795/

相关文章:

c# - 如何在数据网格中将文本显示为粗体?

c# - 如果程序最小化或在系统托盘中,如何检测 ctrl 键被按下两次

actionscript-3 - 每个 MOUSE_DOWN 都保证有一个 MOUSE_UP 吗?

events - 为什么在编译 VB6 应用程序期间会触发事件?

.net - 为什么不识别 HttpUtility 类?

vb.net - 如何扩展任何类型的List类

c# - 如何使用asp按钮执行jQuery脚本?

vb.net - 拆分单词但保留特殊单词

c# - 如何在 Windows 窗体应用程序中以古吉拉特语 native 数字显示数字?

javascript - 使用 Scriptaculous 拖放防止 JavaScript 单击事件