C#事件实现(文章与反射器)

时间:2010-08-19 09:09:30

标签: c# events

公共类EventsType     {         公共事件EventHandler> NewEvent;

    public void SmthHappened(string data)
    {
        MyEventArgs<Object> eventArgs = new MyEventArgs<Object>(data);
        OnNewEvent(eventArgs);
    }

    private void OnNewEvent(MyEventArgs<Object> eventArgs)
    {
        EventHandler<MyEventArgs<Object>> tempEvent = NewEvent;

        if (tempEvent != null)
        {                
            tempEvent(this, eventArgs);
        }
    }
}

我希望C#编译器能像这样翻译NewEvent:

private EventHandler<MyEventArgs<object>> _newEvent;

public event EventHandler<MyEventArgs<object>> NewEvent
{
    [MethodImpl(MethodImplOptions.Synchronized)]
    add
    {
    _newEvent = (EventHandler<MyEventArgs<object>>)Delegate.Combine(_newEvent, value);
    }
    [MethodImpl(MethodImplOptions.Synchronized)]
    remove
    {
    _newEvent = (EventHandler<MyEventArgs<object>>)Delegate.Remove(_newEvent, value);
    }
}

,但Reflector表示它是以这种方式实现的:

public event EventHandler<MyEventArgs<object>> NewEvent
{
    add
    {
        EventHandler<MyEventArgs<object>> handler2;
        EventHandler<MyEventArgs<object>> newEvent = this.NewEvent;
        do
        {
            handler2 = newEvent;
            EventHandler<MyEventArgs<object>> handler3 = (EventHandler<MyEventArgs<object>>) Delegate.Combine(handler2, value);
            newEvent = Interlocked.CompareExchange<EventHandler<MyEventArgs<object>>>(ref this.NewEvent, handler3, handler2);
        }
        while (newEvent != handler2);
    }
    remove
    {
        EventHandler<MyEventArgs<object>> handler2;
        EventHandler<MyEventArgs<object>> newEvent = this.NewEvent;
        do
        {
            handler2 = newEvent;
            EventHandler<MyEventArgs<object>> handler3 = (EventHandler<MyEventArgs<object>>) Delegate.Remove(handler2, value);
            newEvent = Interlocked.CompareExchange<EventHandler<MyEventArgs<object>>>(ref this.NewEvent, handler3, handler2);
        }
        while (newEvent != handler2);
    }
}

拜托,smb解释我为什么会这样?

3 个答案:

答案 0 :(得分:5)

是的,基本上是C# 4 has made some changes in this area。它使其无需锁定即可保证线程安全。这不是唯一的变化 - 它还会改变对类中类字段事件的引用的解决方式:+ =和 - =现在通过“添加”和“删除”位而不是直接使用支持字段。

请注意,此更改会影响使用C#4编译器编译的代码,即使是旧框架也是如此;锁定也发生了变化影响针对.NET 4编译的代码,因为它使用了一种新方法(Monitor.TryEnter(object, out bool))。

答案 1 :(得分:2)

这个问题的答案在很大程度上取决于您使用的版本。多年来它经过了很多改进。见http://blogs.msdn.com/b/cburrows/archive/2010/03/05/events-get-a-little-overhaul-in-c-4-part-i-locks.aspx

答案 2 :(得分:0)

您期望的是一个简单的非线程安全实现。像事件语法这样的字段总是提供线程安全语法(因此是反射器版本)。请参阅此artcile以了解事件&amp;他们是如何实施的。