GUI 事件是否有可能中断 GUI 线程的运行代码以执行其自己的事件处理程序方法?
我的 GUI 代码中有一个奇怪的行为。如果用户在短时间内产生大量事件,则正在运行的事件处理程序方法可能会被另一个事件处理程序方法中断。 由于所有内容都在同一个线程(GUI 线程)中运行,因此所有内容都应该按顺序运行并且不应出现中断,或者我是否误解了什么?
谢谢你的建议, 埃尼
I have a weird behavior in my GUI code. If the user produces a lot of events in a short time, it happens that a running event handler method gets interrupted by another event handler method.
Since everything runs in the same thread (GUI thread) everything should run sequential and an interruption should not be possible, or do I misunderstand something?
Thanks for your advise,
Eny
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
不,那不会发生。您的理解是正确的,线程是按顺序运行的。
GUI线程可以被中断但只能运行不同的线程,它不会重新进入GUI线程来处理另一个事件。一个线程只有一个指令指针,因此只能位于代码中的一处,不能被自身中断。
如果您遇到类似 GUI 线程重新进入的情况,则可能是其他原因。
然而,GUI 头可以通过调用
Application.DoEvents
方法来“中断”自身。No, that doesn't happen. You are right in your understanding that the thread runs sequentially.
The GUI thread can be interrupted but only to run a different thread, it will not re-enter the GUI thread to handle another event. A thread only has one instruction pointer and thus can only be in one place in the code, it can not be interrupted by itself.
If you are experiencing something that look like the GUI thread is re-entered, the reason is something else.
The GUI thead can however "interrupt" itself by calling the
Application.DoEvents
method.您是对的,在单线程应用程序中,事件应该按顺序运行。有一些例外:
事件被触发并调用其订阅者列表中的第一个事件处理程序。事件处理程序触发自己的事件,该事件调用其他事件处理程序。在这种情况下,看起来事件被中断了,但事实并非如此。当原始事件处理程序完成时,将调用列表中的下一个事件处理程序。
事件处理程序调用
Application.DoEvents()
方法。这将挂起当前事件并处理消息队列中等待的任何消息(通常会触发自己的事件),当处理完所有消息时,它将返回到该事件。当Application.DoEvents()
导致对调用它的事件进行递归调用(由于从它处理的消息之一触发事件)时,可能会出现问题。事件处理程序可以在不同的线程上执行。某些事件不会在 UI 线程上触发,并且可能会在其自己的线程上触发。这可能会导致事件无序触发,并在线程上下文切换时相互中断。确保您使用的事件在 UI 线程上触发,如果没有,则
Control.Invoke()
将它们触发到 UI 线程上。 System.Threading.Timer.Elapsed 事件是在单独线程上触发的一个事件示例,您可能没有意识到这一点。You are correct, in a single threaded application, event should be run sequentially. There are a few exceptions:
An event is fired and calls the first event handler in its subscriber list. The event handler fires an event of its own, which calls other event handlers. In this case, it would appear that the event was interrupted, but it was not. When the original event handler completes, the next event handler in the list will be called.
An event handler calls the
Application.DoEvents()
method. This will suspend the current event and process any messages waiting in the message queue (which will usually fire events of their own), and when it has finished processing all messages, it will return to the event. A problem may occur whenApplication.DoEvents()
causes a recursive call to the event which called it, as a result of firing an event from one of the messages it processed.Event handlers may be executed on different threads. Some events are not fired on the UI thread, and may fire on their own thread. This could cause events to be fired out of order and interrupt each other on a thread contexts switch. Make sure that the events you consume are fired on the UI thread, and if not,
Control.Invoke()
them onto the UI thread. An example of an event that is fired on a separate thread, possibly without you being aware of it, is theSystem.Threading.Timer.Elapsed
event.