C# 事件处理程序:何时调用订阅者?

C# event handlers : when are the subscribers invoked?

阅读这里后我认为正在发生的事情,我只是在寻找确认或更正。

为简洁起见,下面的示例将使用匿名 lambda,显然这样做您将失去取消订阅的能力。

MyEvent += (sender, args) => {Console.WriteLine("One")};
MyEvent += (sender, args) => {Console.WriteLine("Two")};
MyEvent += (sender, args) => {Console.WriteLine("Three")};

有了订阅者,我们将调用事件:

var handler = MyEvent;
if(handler != null){
    handler(this, EventArgs.Empty) // <-- Interested in this moment
}

这就是我需要 correcting/clarification/guidance 的地方。据我了解,调用处理程序有效地做的是(我知道它并没有完全这样做,这仅用于说明目的)。

foreach(var subscriber in self){
    subscriber(sender, args);
}

我明确表示不会在 BeginInvoke 中使用它。所以发生的事情基本上是调用处理程序导致处理程序以某种未定义的顺序循环遍历所有订阅者并调用它们从调用线程传递适当的参数(在这个例子中,再次不谈论 BeginInvoke

换句话说,handler(this, EventArgs.Empty) 基本上只是在调用线程上立即执行此操作:

anonymous1(..., ...)
anonymous2(..., ...)
anonymous3(..., ...)

稍微修改以上内容:

var handler = MyEvent;
if(handler != null){
    handler(this, EventArgs.Empty) // <-- Interested in this moment
}

Console.WriteLine("Done Invoking Subscribers");

我们总是可以期望输出是(因为 none 我们的订阅者是异步的并且我们没有使用 BeginInvoke):

// some undefined order of the following 3 lines:

One
Two
Three

// Always followed by
Done Invoking Subscribers

总的来说,我这个想法对吗?

抱歉这么直接,但简单的答案是肯定的,这就是它的工作原理。