The following code snippet is from book Effective C#,
public event AddMessageEventHandler Log;
public void AddMsg ( int priority, string msg )
{
// This idiom discussed below.
AddMessageEventHandler l = Log;
if ( l != null )
l ( null, new LoggerEventArgs( priority, msg ) );
}
The AddMsg method shows the proper way to raise events. The temporary variable to reference the log event handler is an important safeguard against race conditions in
multithreaded programs. Without the copy of the reference, clients could remove event handlers between the if statement check and the execution of the event handler. By
copying the reference, that can’t happen.
Why can a temporary variable stop the client from removing event handler? I must be missing something here.
Delegate chains are immutable. Therefore, if another thread accesses “Log” and removes an eventhandler, Log gets assigned a new delegate chain. Therefore, when l is accessed, even if an eventhandler is removed from Log, it won’t effect l as it will no longer be “pointing” to the same delegate chain. So yes, it does protect against race conditions, however you might end up with a scenario where one thread unsubscribes, but the evanthandler will still be called.