代码改变世界

[转]所见过的最强代码

2010-11-12 18:10  邱鹏  阅读(441)  评论(0)    收藏  举报

http://user.qzone.qq.com/99363590/blog/1276398251

By 大石头

 看了一个半小时,还没有搞清楚是干嘛用的。查了很多资料后才发现,它是如此的精妙!
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%的性能,悲哀呀!