如何防止事件的订阅者相互冲突?

问题描述 投票:0回答:4

假设我有一个有 2 个订阅者的事件(所有事情都发生在同一个线程中) - 一个订阅者写入日志文件,另一个显示消息框。

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

似乎最好的解决方案是让日志编写者在显示消息框的代码之前订阅事件。但是,这里有一个类似的问题:事件订阅者是否按订阅顺序调用?

最好的答案是永远不要依赖订阅者的顺序。那么我如何防止冲突而不担心他们的顺序呢?

c# events event-handling
4个回答
2
投票

所有个人事件订阅者都需要与其他人合作良好。正确的做法是让显示 MessageBox 的事件启动后台线程并从那里显示 MessageBox。


1
投票

根据MSDN C#编程指南中有关事件的文档,事件具有以下属性(重点是粗体):

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

看起来最好的选择是对事件使用 BeginInvoke。


0
投票

编辑:

您可以控制事件代码吗?如果是这样,您可以确保它永远不会以一种病态的奇怪方式来重新排序。您甚至可以将其记录为事件本身的一部分:“始终按订阅顺序同步调用此事件的处理程序。”

说实话,我真的希望任何与之相关的事件都能明确记录下来。


0
投票

将时间戳添加为

EventArgs
类的属性。将该时间戳写入日志文件,忘记写入日志时的时钟时间。这样它就真正代表了事件发生的时刻,而不是写入日志文件的任意时间。

© www.soinside.com 2019 - 2024. All rights reserved.