• C#内部关于绑定事件Event的线程安全


    private EventHandler _FieldsChanged;
    public event EventHandler FieldsChanged
    {
        add
        {
            EventHandler handler2;
            EventHandler fieldsChanged = this._FieldsChanged;
            do
            {
                handler2 = fieldsChanged;
                EventHandler handler3 = (EventHandler)Delegate.Combine(handler2, value);
                fieldsChanged = Interlocked.CompareExchange<EventHandler>(ref this._FieldsChanged, handler3, handler2);
            }
            while (fieldsChanged != handler2);
        }
        remove
        {
            EventHandler handler2;
            EventHandler fieldsChanged = this._FieldsChanged;
            do
            {
                handler2 = fieldsChanged;
                EventHandler handler3 = (EventHandler)Delegate.Remove(handler2, value);
                fieldsChanged = Interlocked.CompareExchange<EventHandler>(ref this._FieldsChanged, handler3, handler2);
            }
            while (fieldsChanged != handler2);
        }
    }
        下面是我最后的理解,也许是错的:
    EventHandler handler2;
    EventHandler fieldsChanged = this._FieldsChanged;
    do
    {
        // 两个本地变量都保存着_FieldsChanged的本地引用
        handler2 = fieldsChanged;
        // 事件绑定。这是唯一一句业务代码
        EventHandler handler3 = (EventHandler)Delegate.Combine(handler2, value);
        // 如果_FieldsChanged等于handler2,就执行_FieldsChanged=handler3,这里是原子操作,线程安全
        // 如果不等,很明显,有线程冲突存在,数据被别的线程修改过了,这里返回_FieldsChanged到fieldsChanged中去
        fieldsChanged = Interlocked.CompareExchange<EventHandler>(ref this._FieldsChanged, handler3, handler2);
    }
    while (fieldsChanged != handler2);

    // 实际上,整个过程,如果不考虑线程安全,可以直接这么写
    _FieldsChanged = (EventHandler)Delegate.Combine(_FieldsChanged, value);
    // 这段代码的精妙之处就在于这个线程安全,如果Combine后,别的线程也进来,那就出现了数据丢失
    // 当然,常规做法可以是Lock住这段代码,但是,线程冲突的可行性不到1%,为此损失了99%的性能,悲哀呀! 
    采集
  • 相关阅读:
    Block为什么使用Copy?
    iOS运行时,如何增加成员变量
    安卓长按交互onCreateContextMenu的简单 用法
    iOS 检查版本号的代码
    git的基本使用
    svn的使用
    const 关键字及作用
    常见的内存分配
    保存字符串的方法
    指针的总结一(指针的定义)
  • 原文地址:https://www.cnblogs.com/wwwzzg168/p/4121547.html
Copyright © 2020-2023  润新知