假设按订阅顺序调用事件订阅者是否安全?
例:
void One(object sender, EventArgs e) {} void Two(object sender, EventArgs e) {} event EventHandler foo; foo += One; foo += Two;
当事件被触发时,One()总是在Two()之前调用吗?
编辑:
你应该不依赖它,我只是想.这个想法是,多播代表与COMMAND模式类似.所以我只是想知道.通常你会使用一个保存COMMAND命令的集合,这样你就可以做undo/redo/whatever.
鉴于该实现,是的,它们将始终按该顺序调用.
如果事件实际上使用了一些处理订阅的奇怪和奇妙的方式,它可以做不同的事情 - 但"正常"的实现将做正确的事情.
要清楚,订阅事件处理程序只意味着调用事件的相应"添加"部分.如果事件通过执行以下操作来处理此事:
myHandler += value;
被翻译成
myHandler = Delegate.Combine(myHandler, value);
和Delegate.Combine保证订购.但是,如果你有这样的事件:
private LinkedListeventHandlers = new LinkedList ; public event EventHandler Foo { add { eventHandlers.AddFirst(value); } remove { // do stuff here too } }
通过执行以下操作来解雇事件:
foreach (EventHandler handler in eventHandlers) { handler(this, EventArgs.Empty); }
然后将以相反的顺序调用处理程序.
简介:对于所有理智的事件,您可以依赖订购.从理论上讲,事件可以做他们喜欢的事情,但我从未见过一个不能保持适当排序的事件.
密切关注Jon Skeet给出的警告 - "鉴于实施......".换句话说,进行最轻微的更改(多个线程,其他处理程序等),您可能会失去执行顺序不变性.
千万不要依赖于事件排序.所有事件调度都应该在逻辑上独立,就好像它们是并行发生的一样.事件是逻辑上独立的操作.
我会更进一步,并断言如果你必须承担一个事件发射的命令,你有一个严重的设计缺陷和/或滥用事件.
即使以正确的顺序调用它们,我也会尝试不编写依赖于前一个委托被解雇的代码以使其正常运行.
如果Two()依赖于One()所做的事情,那么要么附加一个以正确顺序调用这两个方法的委托,要么让Two()在必要时调用One().