C#事件实现(文章vs反射器) [英] The C# events implementation (articles vs reflector)

查看:98
本文介绍了C#事件实现(文章vs反射器)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

public class EventsType
{
public event EventHandler> NewEvent;

  public void SmthHappened(string数据)
{
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)]
添加
{
_newEvent =(EventHandler< MyEventArgs< object>)Delegate.Combine(_newEvent,值);
}
[MethodImpl(MethodImplOptions.Synchronized)]
删除
{
_newEvent =(EventHandler< MyEventArgs< object>)Delegate.Remove(_newEvent,value );
}
}

,但反射器说这是以这种方式实现的:

  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);
}
删除
{
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解释一下为什么会这样?

解决方案

Yup: C#4在这方面做了一些改变。它使得线程安全无锁定。这不是唯一的改变 - 它也改变了类中类场景事件的引用如何解决:+ =和 - =现在通过添加和删除位,而不是直接使用后备字段。 p>

请注意,此更改会影响使用C#4编译器编译的代码,即使对较旧的框架;因为它使用了一种新的方法( Monitor.TryEnter(object,out bool) )。


public class EventsType { public event 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);
        }
    }
}

I expected that the C# compiler will translate the NewEvent like this:

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);
    }
}

, but the Reflector says that it is implemented this way:

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);
    }
}

Please, smb explain me why is it so?

解决方案

Yup: C# 4 has made some changes in this area, basically. It makes it thread-safe without locking. That's not the only change - it also changes how references to field-like events within the class are resolved: += and -= now go through the "add" and "remove" bits rather than working directly with the backing field.

Note that this change affects code compiled with the C# 4 compiler even against older frameworks; there are also changes to locking which only affect code compiled against .NET 4, as it uses a new method (Monitor.TryEnter(object, out bool)).

这篇关于C#事件实现(文章vs反射器)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆