`

Anatomy on the event add/remove handler

    博客分类:
  • C#
c# 
阅读更多

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. 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics