【问题标题】:.NET Event Handling When an Event Is Fired While Another Event Handler is Already Running.NET 事件处理在另一个事件处理程序已在运行时触发事件
【发布时间】: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


【解决方案1】:

这与 CLR 或语言无关。它纯粹基于定义方法的类的具体实现。它可以写成在先前调用的处理程序仍在运行时触发事件,或者它不能。如果您正在处理一个 winforms 程序,那么大多数对象触发事件都会在 UI 线程中触发它们,因此由于只有一个线程可以触发事件,因此在其他处理程序仍在运行时它永远无法触发它们,但是还有其他对象不会强制它们使用单​​个线程,因此可以在先前调用的处理程序仍在运行时触发事件。

因此,您真正能做的就是查看文档/源代码或进行一些实验测试以查看任何特定类的作用,或者确保安全并假设最坏的情况。没有一般的案例答案。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多