我的 GUI 代码中有一个奇怪的行为。如果用户在短时间内产生大量事件,则可能会发生正在运行的事件处理程序方法被另一个事件处理程序方法中断。由于一切都在同一个线程(GUI 线程)中运行,一切都应该按顺序运行,并且不应出现中断,还是我误解了什么?
谢谢你的建议,恩尼
我的 GUI 代码中有一个奇怪的行为。如果用户在短时间内产生大量事件,则可能会发生正在运行的事件处理程序方法被另一个事件处理程序方法中断。由于一切都在同一个线程(GUI 线程)中运行,一切都应该按顺序运行,并且不应出现中断,还是我误解了什么?
谢谢你的建议,恩尼
不,这不会发生。您对线程按顺序运行的理解是正确的。
GUI线程可以被中断但只能运行不同的线程,它不会重新进入GUI线程来处理另一个事件。一个线程只有一个指令指针,因此只能在代码中的一个地方,它不能被自己中断。
如果您遇到的情况看起来像是重新进入了 GUI 线程,原因是其他的。
然而,GUI 头可以通过调用该Application.DoEvents
方法“中断”自身。
你是对的,在单线程应用程序中,事件应该按顺序运行。有几个例外:
触发一个事件并调用其订阅者列表中的第一个事件处理程序。事件处理程序触发它自己的事件,该事件调用其他事件处理程序。在这种情况下,事件似乎被中断,但事实并非如此。当原始事件处理程序完成时,将调用列表中的下一个事件处理程序。
事件处理程序调用该Application.DoEvents()
方法。这将暂停当前事件并处理消息队列中等待的任何消息(通常会触发它们自己的事件),当它处理完所有消息后,它将返回到该事件。当递归调用调用它的事件时,可能会出现问题Application.DoEvents()
,这是从它处理的消息之一触发事件的结果。
事件处理程序可以在不同的线程上执行。某些事件不会在 UI 线程上触发,并且可能会在它们自己的线程上触发。这可能会导致事件被无序触发并在线程上下文切换时相互中断。确保您使用的事件在 UI 线程上触发,如果没有,则在 UI 线程上触发Control.Invoke()
。在单独的线程上触发的事件的一个示例就是System.Threading.Timer.Elapsed
事件。