我使用 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版本有所不同)
Interlocked.CompareExchange 将第一个参数与第三个参数进行比较,如果它们相等,则将第一个参数替换为第二个参数。这是一个线程安全的操作。循环用于分配变量 eventHandler2 之后且检查之前,另一个线程更改此委托的情况。在这种情况下,Interlocked.CompareExchange 不会执行交换,循环条件不会评估为 true,并且会进行下一次尝试。
C# 3 在事件处理程序中生成简单的代码:
add { lock(this) { changed = changed + value; } }
其性能较低并且可能会导致死锁。
关于这个主题有一系列很棒的文章:
C# 4 中的事件进行了一些修改
C# 4 第二部分中的事件得到了一些修改
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)