当前位置:  开发笔记 > 编程语言 > 正文

事件订阅者是按订阅顺序调用的吗?

如何解决《事件订阅者是按订阅顺序调用的吗?》经验,为你挑选了3个好方法。

假设按订阅顺序调用事件订阅者是否安全?
例:

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.



1> Jon Skeet..:

鉴于该实现,是的,它们将始终按该顺序调用.

如果事件实际上使用了一些处理订阅的奇怪和奇妙的方式,它可以做不同的事情 - 但"正常"的实现将做正确的事情.

要清楚,订阅事件处理程序只意味着调用事件的相应"添加"部分.如果事件通过执行以下操作来处理此事:

myHandler += value;

被翻译成

myHandler = Delegate.Combine(myHandler, value);

和Delegate.Combine保证订购.但是,如果你有这样的事件:

private LinkedList eventHandlers = 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,你比大多数人更了解一个人永远不应该依赖事件处理程序的执行顺序; 你为什么要放这张幻灯片?

2> Steven A. Lo..:

密切关注Jon Skeet给出的警告 - "鉴于实施......".换句话说,进行最轻微的更改(多个线程,其他处理程序等),您可能会失去执行顺序不变性.

千万不要依赖于事件排序.所有事件调度都应该在逻辑上独立,就好像它们是并行发生的一样.事件是逻辑上独立的操作.

我会更进一步,并断言如果你必须承担一个事件发射的命令,你有一个严重的设计缺陷和/或滥用事件.



3> Paul..:

即使以正确的顺序调用它们,我也会尝试不编写依赖于前一个委托被解雇的代码以使其正常运行.

如果Two()依赖于One()所做的事情,那么要么附加一个以正确顺序调用这两个方法的委托,要么让Two()在必要时调用One().

推荐阅读
ar_wen2402851455
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有