2009-12-10 95 views
2

假设我有一个有2个订阅者的事件(一切发生在同一个线程中) - 一个订阅者写入日志文件,另一个订阅者显示一个MessageBox。如何防止订阅者发生冲突的事件?

如果MessageBox是订阅列表中的第一个,那么直到用户关闭消息框后才会写入日志条目。因此,日志条目中的时间确实是消息框关闭的时间,而不是事件发生的时间。

看来最好的解决方案是让日志编写器在显示消息框的代码之前订阅事件。然而,在这里类似的问题:Are event subscribers called in order of subscription?

最好的答案是永远不依赖于订户的顺序。那么,如何避免冲突而不必担心他们的订单呢?

回答

0

编辑:

您是否在控制事件代码?如果是这样,你可以确保它从来没有以一种病态的奇怪方式实现重新排序。您甚至可以将其作为事件本身的一部分进行记录:“此事件的处理程序始终以订阅顺序同步调用。”

说实话,我真的希望任何事件没有去明确地记录它。

+1

对不起 - 我指的是S. Lowe的回答 – 2009-12-10 22:53:39

+0

@ R.B。 - 好的,但同样的逻辑适用。你是否在控制事件代码,所以可以保证它不会搅乱事物? – 2009-12-10 23:12:03

+0

我有控制事件代码,但不是订阅者。 – 2009-12-10 23:21:50

2

所有的个人事件用户都需要和其他人一起玩。正确的事情是显示MessageBox启动后台线程并显示MessageBox的事件。

+0

这是否会奏效 - 我认为所有UI都必须来自主线程。 – ChrisF 2009-12-10 22:52:22

+0

您可以从另一个线程创建一个弹出窗口,但编辑主窗体更具挑战性。 – 2009-12-10 22:54:48

+0

在后台创建的消息框不会保持在最前面。 – 2009-12-10 22:57:07

1

根据所MSDN C# programming guide上的事件的文档,事件具有以下性质(关键点是粗体显示):

  • 发布者确定何时引发事件;订户确定响应该事件采取了什么行动。
  • 一个事件可以有多个订阅者。订户可以处理来自多个发布者的多个事件。
  • 没有订户的事件永远不会被提出。
  • 事件通常用于表示图形用户界面中的用户操作,例如按钮点击或菜单选择。
  • 当一个事件有多个订阅者时,事件处理程序在引发事件时被同步调用。要异步调用事件,请参阅Calling Synchronous Methods Asynchronously
  • 事件可用于同步线程。
  • 在.NET Framework类库中,事件基于EventHandler委托和EventArgs基类。

看起来最好的办法就是在事件上使用BeginInvoke。