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

时间:2015-04-11 14:50:32

标签: c# multithreading events event-handling

在做了一些阅读后,我认为这是正在发生的事情,我只是在寻找确认或纠正。

下面的示例将使用匿名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
}

所以我需要更正/澄清/指导。据我所知,调用处理程序实际上正在做的是(我明白它并没有完全做到这一点,这只是为了说明目的)。

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

我明确没有谈到将此与BeginInvoke一起使用。所以发生的事情基本上是调用处理程序导致处理程序以某种未定义的顺序遍历所有的订阅者,并调用它们从调用线程传递适当的args(在这个例子中,再次不是在谈论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");

我们总是可以期望输出(因为我们的订户都不是异步的,我们没有使用BeginInvoke):

// some undefined order of the following 3 lines:

One
Two
Three

// Always followed by
Done Invoking Subscribers

一般来说,我有这个想法吗?

1 个答案:

答案 0 :(得分:3)

很抱歉这是直接的,但简单的答案是肯定的,它是如何运作的。