微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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,尽管这个“修复”.

原文地址:https://www.jb51.cc/csharp/96295.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐