【发布时间】:2016-03-22 23:33:40
【问题描述】:
有一个问题让我好奇了好久。
假设这种情况:
您在 C# 中创建了一个程序,其中有一些您在其中定义了一些事件的类,
和其他类使用这些事件 - 它们为它们实现事件处理程序方法。
我的问题: 对于事件同时发生的情况,CLR 运行事件处理程序的“规则”是什么?
如果一个事件处理程序正在运行,并且现在引发了另一个事件,CLR 是否会让当前事件处理程序完成,然后转到下一个事件处理程序? (“第二个”事件可能是同一事件或不同事件的第二次引发)
或者是否存在 CLR 由于中间出现事件而暂停当前事件处理程序的情况,然后运行第二个事件处理程序,然后又恢复到离开的第一个事件处理程序的中间?
任何在此下订单的信息或文章,将不胜感激。
顺便说一句:
对于这个问题,请假设两种可能的情况:
1) 具有事件和事件处理程序的类不是控件
(您编写的简单类,继承类型 object 而不是类型 Control)
2) 具有事件和事件处理程序的类继承了 Control 类(Windows 窗体)
我提到这一点是因为两者之间的行为/规则可能不同。
另外,如果您能提及以下可能会影响这两个问题的答案的事情,我将不胜感激:
- Application.DoEvents() 方法
- 计时器s
- 除了我们在“正常”情况下可能想到的简单结果之外,任何其他类似的类/方法可能会产生不同的结果..
谢谢
【问题讨论】:
-
如果是单线程的,它们不能“同时发生”,如果是多线程的,那么两者都会同时发生。
-
意外重入是 UI 应用程序等具有事件循环的应用程序中的事件处理程序的常见问题。我想这将被视为当前方法的“暂停”,但它不受任何 CLR 策略的控制。造成这种情况的是应用程序事件循环的设计。
-
嗨,迈克。谢谢,您能否详细说明一下,或者参考我可以了解更多信息的地方? (比如它可能发生的地方,在我们想要阻止的情况下可以做些什么来阻止它,可以做些什么来启用它,在我们真正希望它发生的地方等等)
-
@spaceman 这个answer by Eric Lippert 用一个玩具示例很好地说明了该场景,该示例是在普通 UI 应用程序中运行的消息循环的简化版本。请注意,
Application.DoEvents正是他警告过的那种“泵送消息循环”的方法。
标签: c# .net winforms events eventhandler