If you don’t specify your own event add/remove handlers, the C# compiler generates this add handler (reconstructed by .NET Reflector):
public void add_MyEvent(EventHandler value)
{
EventHandler handler2;
EventHandler myEvent = this.MyEvent;
do
{
handler2 = myEvent;
EventHandler handler3 = (EventHandler) Delegate.Combine(handler2, value);
myEvent = Interlocked.CompareExchange<EventHandler>(ref this.MyEvent, handler3, handler2);
}
while (myEvent != handler2);
}
and a remove handler that looks the same but with Delegate.Remove
instead of Delegate.Combine
.
Notice the use of Interlocked.CompareExchange
? This prevents a race condition between updating the event’s backing field and reading from it. Thus, it is thread-safe.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…