2013-03-26 138 views
2

我反编译使用ILSpy组件,特别是一类了我的注意:反编译汇编 - 异常代码

public class CustomTextStream : NetworkStream 
{ 
    private EventHandler<CustomEventArgs> someEvent; 
    public event EventHandler<CustomEventArgs> SomePublicEvent 
    { 
     add 
     { 
      EventHandler<CustomEventArgs> eventHandler = this.someEvent; 
      EventHandler<CustomEventArgs> eventHandler2; 
      do 
      { 
       eventHandler2 = eventHandler; 
       EventHandler<CustomEventArgs> value2 = 
        (EventHandler<CustomEventArgs>)Delegate.Combine(eventHandler2, value); 
       eventHandler = 
        Interlocked.CompareExchange<EventHandler<CustomEventArgs>>(
        ref this.someEvent, value2, eventHandler2); 
      } 
      while (eventHandler != eventHandler2); 
     } 
     remove 
     { 
      // similar stuff... 
     } 
    } 
} 
代码

而且,似乎是私人委托用于火灾实际事件:

if (something != null && somethingElse != 0) 
{ 
    this.someEvent(this, new CustomEventArgs(someArg)); 
} 

问题:假设某些“编译/反编译魔法”没有发生,有人可以猜测这个自定义访问器背后的想法是什么吗?我没有太多熟悉IL,顺便说一句...

(旁注:应用是多线程的,利用网络,很明显。)

+0

看起来像第一眼默认代码 - 正常的“事件”其实是一些接近这个代码。考虑尝试使用事件而不是反编译来创建代码。 – 2013-03-26 19:58:06

+1

我看到奇怪的东西,像这样产生的混淆器只是为了混淆你。 – NickD 2013-03-26 19:58:59

+0

@Alexei Levenkov我已经做到了。我没有得到相同的结果。 “正常”反编译事件中唯一的事情是'Delegate.Combine()'部分 – Less 2013-03-26 19:59:45

回答

8

这是由编译器生成一个新的事件处理程序代码。它在C#4中引入(C#3版本不同)

Interlocked.CompareExchange将第一个参数与第三个参数进行比较,如果它们相等,则用第二个参数替换第一个参数。这是一个线程安全的操作。循环用于在分配变量eventHandler2之后并在检查之前,另一个线程更改此代理。在这种情况下,Interlocked.CompareExchange不执行交换,循环条件不计算为真,并进行下一次尝试。

C#3生成的事件处理程序简单的代码:

add { lock(this) { changed = changed + value; } } 

其中有较低的性能,并可能导致死锁。

有一个伟大的系列关于这个问题的文章:

Events get a little overhaul in C# 4

Events get a little overhaul in C# 4, Part II