反编译的程序集-异常代码

本文关键字:异常 代码 程序集 编译 | 更新日期: 2023-09-27 18:06:04

我使用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不太熟悉,顺便说一句……

(边注:应用程序是多线程的,显然利用了网络)

反编译的程序集-异常代码

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

联锁。CompareExchange比较第一个参数和第三个参数,如果它们相等,则用第二个参数替换第一个参数。这是一个线程安全的操作。循环用于在分配变量eventHandler2之后,在check之前,另一个线程更改此委托的情况。在这种情况下,互锁。CompareExchange不执行交换,循环条件不计算为true,并进行下一次尝试。

c# 3在事件处理程序中生成了简单的代码:
add { lock(this) { changed = changed + value; } }

性能较低,并且可能引入死锁。

有很多关于这个主题的文章:

事件在c# 4中得到了一些改进

c# 4对

事件进行了一些修改,第二部分