问题描述
有以下方式,用来避免竞态条件从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#语言规范有什么看法事件和委托,但它并没有解决这个问题。
感谢您的时间。
虽然你是正确的,委托类型是引用类型,它们的一成不变的引用类型。从<$c$c>System.Delegate$c$c>:
在另一方面,这种模式解决了唯一的问题是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.
Although you are correct that delegate-types are references-types, they are immutable reference-types. From System.Delegate
:
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:如何在事件处理程序竞争条件修复工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!