.NET:如何在事件处理程序竞争条件修复工作? [英] .NET: How does the EventHandler race-condition fix work?

查看:144
本文介绍了.NET:如何在事件处理程序竞争条件修复工作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有以下方式,用来避免竞态条件从MyEvent万一引发事件时另一线程退订,使它空

  MyClass类
{
    公共事件的EventHandler MyEvent;

    公共无效F()
    {
        事件处理程序处理程序= MyEvent;
        如果(处理!= NULL)
            处理程序(这一点,EventArgs.Empty);
    }
}
 

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

  MyClass类
{
    公共事件的EventHandler MyEvent;

    公共无效F()
    {
        如果(MyEvent!= NULL)
            MyEvent(这一点,EventArgs.Empty);
    }
}
 

我的问题是,因为 System.Delegate 是引用类型:万一MyEvent不为空,怎么来的

 事件处理程序处理程序= MyEvent;
 

好像的复制的它的调用列表,而不是的获得的参考。

我预计其分配到处理变量MyEvent委托,那么一旦有人的修改的MyEvent,这一处理程序参考文献将被改变,以及对象。

显然,这是不是这样的,否则这个漂亮的小图案是行不通的。

我已经研究过了.NET源$ C ​​$ C,仍然找不到我的答案,(它可能有,但我已经找了大约一个小时,也没有找到,所以我在这里。 ) 我也看到了什么是C#语言规范有什么看法事件和委托,但它并没有解决这个问题。

感谢您的时间。

解决方案
  

我希望,一旦我得到了   在处理程序里面MyEvent委托   基准,一旦有人将改变   MyEvent的对象,处理   参考文献也将被改变。   [..]   请注意,System.Delegate是一个类,而不是一个结构。

虽然你是正确的,委托类型是引用类型,它们的一成不变的引用类型。从<一个href="http://msdn.microsoft.com/en-us/library/system.delegate.aspx"><$c$c>System.Delegate:

  

代表是不可改变的; 一次   创建一个调用列表   委托不改变。 [...]   组合操作,如结合   和删除,不改变现有的   与会代表。相反,这样的   操作返回一个新的委托,该委托   包含操作的结果,   不变的委托,还是一无所获。


在另一方面,这种模式解决了唯一的问题是preventing的空委托引用尝试调用。事件是容易的比赛尽管这种修复

There's the following pattern which is used to avoid a race condition when raising events in case another thread unsubscribes from MyEvent, making it null.

class MyClass
{
    public event EventHandler MyEvent;

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

as opposed to the wrong way of doing it which is prone to this race condition:

class MyClass
{
    public event EventHandler MyEvent;

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

My question is, given that System.Delegate is a reference type: in case MyEvent is not null, how come

EventHandler handler = MyEvent;

seems to copy its invocation list instead of obtaining the reference.

I would expect that having the MyEvent delegate assigned to the 'handler' variable, then once somebody changed MyEvent that the object that 'handler' references would be changed as well.

Obviously, that is not the case, otherwise this nifty little pattern wouldn't work.

I've looked into the .NET source code and still could not find my answer there (it's probably there, but I've looked for about an hour and couldn't find it, so here I am.) I've also read what the C# Language Specification has to say about events and delegates, but it doesn't address this matter.

Thanks for your time.

解决方案

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.

Although you are correct that delegate-types are references-types, they are immutable reference-types. From 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.


On another note, the only issue this pattern addresses is preventing the attempted invocation of a null delegate-reference. Events are prone to races despite this "fix".

这篇关于.NET:如何在事件处理程序竞争条件修复工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆