Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/305.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 是否按订阅顺序调用事件订阅服务器?_C#_.net_Events_.net 2.0_C# 2.0 - Fatal编程技术网

C# 是否按订阅顺序调用事件订阅服务器?

C# 是否按订阅顺序调用事件订阅服务器?,c#,.net,events,.net-2.0,c#-2.0,C#,.net,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; 触发事件时,是否总是在调用2()之前调用1() 编辑: 你们当然不应该依赖它,我只是在想。其思想是,多播委托与命令模式类似。所以我只是想知道。通常情况下,您会使用一个集合来保持命令的

假设事件订阅服务器是按订阅顺序调用的,安全吗?
例如:

void One(object sender, EventArgs e) {}
void Two(object sender, EventArgs e) {}

event EventHandler foo;

foo += One;
foo += Two;
触发事件时,是否总是在调用2()之前调用1()

编辑:

你们当然不应该依赖它,我只是在想。其思想是,多播委托与命令模式类似。所以我只是想知道。通常情况下,您会使用一个集合来保持命令的顺序,这样您就可以执行undo/redo/任何操作。

考虑到该实现,是的,它们将始终按该顺序调用

如果事件实际上使用了一些奇怪而奇妙的方式来处理订阅,那么它可以做不同的事情——但是“正常”的实现会做正确的事情

明确地说,订阅事件处理程序只意味着调用事件的适当“添加”部分。如果事件通过执行以下操作来处理此问题:

myHandler += value;
foreach (EventHandler handler in eventHandlers)
{
    handler(this, EventArgs.Empty);
}
这被翻译成

myHandler = Delegate.Combine(myHandler, value);
并保证订购。但是,如果您有这样的活动:

private LinkedList<EventHandler> eventHandlers = new LinkedList<EventHandler>;

public event EventHandler Foo
{
    add
    {
        eventHandlers.AddFirst(value);
    }
    remove
    {
        // do stuff here too
    }
}
然后以相反的顺序调用处理程序


摘要:对于所有sane事件,您可以依赖于顺序。理论上,事件可以随心所欲,但我从未见过不保持适当顺序的事件。

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


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

请密切注意Jon Skeet给出的警告——“给定该实现…”。换言之,只要稍作更改(多线程、其他处理程序等),就有可能失去执行不变性的顺序

不要依赖事件顺序。所有事件调度在逻辑上都应该是独立的,就好像它们是并行发生的一样。事件是逻辑上独立的动作

我将更进一步,并断言,如果您必须假设事件触发顺序,则您存在严重的设计缺陷和/或误用事件。

快速回答将是“这不关您的事”:

事件本质上是异步的。这意味着您不是在等待触发事件,也不是期望事件在给定时间发生。他们只是发生,然后你采取行动。想要知道“什么时候”或试图找出“如何”将打破这种本性

也许在这种情况下,您不需要基于事件的方法来完成任务


Jon Skeet所说的对于当前的实现在技术上是正确的,但在c#8.5或VBasic 15.0中可能不会。依赖于实现细节总是弊大于利。

一般来说,事件订阅者的行为应该彼此独立。无论它们是按订阅顺序调用、按订阅的相反顺序调用,还是按看似随机的顺序调用,每次引发事件时都会发生任意变化,这都应该没有区别。订阅者不应该关心在他们之前或之后执行的其他订阅者


然而,在某些情况下,事件可以在这种排序很重要的上下文中使用。事件处理程序可能被传递给一个可变对象,并被期望利用该对象先前处理程序的突变。在这种情况下,如果事件的有意义的操作需要按照特定的顺序执行,并且只要遵守了对订阅者的任何书面要求,就应该预期事件将按照给定的顺序执行。

Dupe of Jon,您比大多数人都更清楚,永远不应该依赖事件处理程序的执行顺序;你为什么要让这条消息溜走呢?而且,我想说,没有这样一种正确的方式来通知订阅者。