任何人都知道 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 。窗口过程通常称为WindowProc
或WndProc
。在.NET WinForm项目中,消息循环是通过调用Application.Run
启动的。
关于深入处理 VB.NET 事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21484795/