Anatomy on the event add/remove handler

If you open a C# class, and if the C# class has event delcared, then you might be able to see code as follow. 

    // Events
    internal event EventHandler<ModuleInitializeArgs> AfterModuleInitialized
    {
        add
        {
            EventHandler<ModuleInitializeArgs> handler2;
            EventHandler<ModuleInitializeArgs> afterModuleInitialized = this.AfterModuleInitialized;
            do
            {
                handler2 = afterModuleInitialized;
                EventHandler<ModuleInitializeArgs> handler3 = (EventHandler<ModuleInitializeArgs>) Delegate.Combine(handler2, value);
                afterModuleInitialized = Interlocked.CompareExchange<EventHandler<ModuleInitializeArgs>>(ref this.AfterModuleInitialized, handler3, handler2);
            }
            while (afterModuleInitialized != handler2);
        }
        remove
        {
            EventHandler<ModuleInitializeArgs> handler2;
            EventHandler<ModuleInitializeArgs> afterModuleInitialized = this.AfterModuleInitialized;
            do
            {
                handler2 = afterModuleInitialized;
                EventHandler<ModuleInitializeArgs> handler3 = (EventHandler<ModuleInitializeArgs>) Delegate.Remove(handler2, value);
                afterModuleInitialized = Interlocked.CompareExchange<EventHandler<ModuleInitializeArgs>>(ref this.AfterModuleInitialized, handler3, handler2);
            }
            while (afterModuleInitialized != handler2);
        }
    }

 

You may wonder why all the hassle when you you just wantted to comine a handler to an event field. 

but let's see why this??

in multple situation, it is common that you lost update, where event are immutable, when you combine a event with a event handler, then a new event will be returned, so before you switch the combined result with the event field, if there is another thread kicks in and stole the update, where it has updated the AfterModuleInitialized event , and then the forestalled thread resume, and it is highly possible the thread will eat up another thread's update.  So it will check to see if the this.AfterModuleInitialized  is the same as the handler (which store the this.AfterModuleInitialized  's old value), if there is no other thread steals the update, then it is safe to proceed, otherwise, it will do another round until it succes. 

你可能感兴趣的:(C#)