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