类似现场的事件实现

Field-like implementation of events

最近我试图了解事件的类似字段的实现。 MSIL 代码不够清晰,所以我用 sharplab.io 查看没有语法糖的 c# 代码,得到了这个:

private Action m_Someevent;

public event Action Someevent
{
    [CompilerGenerated]
    add
    {
        Action action = this.m_Someevent;
        Action action2;
        do
        {
            action2 = action;
            Action value2 = (Action)Delegate.Combine(action2, value);
            action = Interlocked.CompareExchange(ref this.m_Someevent, value2, action2);
        }
        while ((object)action != action2);
    }
    [CompilerGenerated]
    remove
    {
        Action action = this.m_Someevent;
        Action action2;
        do
        {
            action2 = action;
            Action value2 = (Action)Delegate.Remove(action2, value);
            action = Interlocked.CompareExchange(ref this.m_Someevent, value2, action2);
        }
        while ((object)action != action2);
    }
}

do while循环有什么用?我已经调试了很多订阅案例,并且总是只循环一次。我有一个想法,它用于 invocattionlist 上的迭代,但它是错误的。

事件的添加和删除被设计成原子性的,即使是面对多线程的情况。您应该能够从两个线程订阅给定的事件,并确保两者都被添加。

这是通过读取基础字段的值,将委托与要添加的委托结合起来,尝试将其分配回该字段,并且仅当您将其分配回时字段中的值才继续进行是在您添加您的值之前最初存在的值。实际上,它是在检查您在前面几行代码中执行工作时基础字段是否发生了变化。如果有,它会再次尝试,直到在字段的获取和设置之间没有发生任何其他事情。