C#eventhandler如何在内部工作?

hid*_*yat 4 c# event-handling

我猜C#evenhandler有一个监听器列表,它在发送消息时通过列表循环.我的问题是这是如何在内部工作的.它是否在循环之前制作列表的副本,如果是这样,如果有人在复制列表之后取消注册但尚未收到消息,会发生什么.

即使它已取消注册,它仍会得到消息吗?

Mar*_*ell 6

委托是不可变的,因此当您调用委托时,已知并修复了订户列表.订阅或取消订阅将替换支持事件的委托.

这确实意味着在多线程场景中,您可以取消订阅收到一个事件,因为:

  1. 委托已经在被调用的过程中
  2. 为了调用,已经获得了委托的快照

2,我的意思是通常的模式(防止在调用期间使用null-ref):

var handler = SomeEvent;
// <===== another thread could unsubscribe at this point
if(handler != null) handler(sender, args); // <== or part way through this invoke
// (and it either case, have the event trigger even though they think they have
// unsubscribed)
Run Code Online (Sandbox Code Playgroud)

因此,如果你是编码复杂的多线程代码的事件,你应该在代码防守使得事件触发后,你认为你已经取消订阅是没有问题的.

这些细微差别并不会真正影响单线程代码.