c# – .NET:EventHandler种族条件解决方案如何工作?

前端之家收集整理的这篇文章主要介绍了c# – .NET:EventHandler种族条件解决方案如何工作?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
有以下模式用于避免竞争条件,当提出事件时,如果另一个线程取消订阅从MyEvent,使其为空.
class MyClass
{
    public event EventHandler MyEvent;

    public void F()
    {
        EventHandler handler = MyEvent;
        if(handler != null)
            handler(this,EventArgs.Empty);
    }
}

而不是这样做的错误方式,容易出现这种竞争状况:

class MyClass
{
    public event EventHandler MyEvent;

    public void F()
    {
        if(MyEvent != null)
            MyEvent(this,EventArgs.Empty);
    }
}

我的问题是,鉴于System.Delegate是一个引用类型:如果MyEvent不为null,那怎么来了

EventHandler handler = MyEvent;

似乎复制其调用列表,而不是获取引用.

我希望将MyEvent委托分配给’handler’变量,那么一旦有人改变了MyEvent,那么’handler’引用的对象也会被改变.

显然,情况并非如此,否则这个漂亮的小样式将不起作用.

我已经研究了.NET源代码,但仍然找不到我的答案(可能在那里,但是我已经找了一个小时,找不到它,所以我在这里)
我也看过C#语言规范对事件和代表的看法,但是并没有解决这个问题.

谢谢你的时间.

解决方法

I would expect that once I got the
MyEvent delegate inside the ‘handler’
reference,once somebody would change
MyEvent that the object that ‘handler’
references will be changed as well.
[..]
Notice that System.Delegate is a class and not a struct.

尽管委托类型是引用类型是正确的,但它们是不可变的引用类型.从System.Delegate

“Delegates are immutable; once
created,the invocation list of a
delegate does not change.
[…]
Combining operations,such as Combine
and Remove,do not alter existing
delegates. Instead,such an
operation returns a new delegate that
contains the results of the operation,
an unchanged delegate,or Nothing.

另一方面,这种模式解决的唯一问题是阻止尝试调用一个空委托引用.事件是prone to races,尽管这个“修复”.

猜你在找的C#相关文章