gpt4 book ai didi

c# - .NET:EventHandler 竞争条件修复如何工作?

转载 作者:可可西里 更新时间:2023-11-01 08:41:40 24 4
gpt4 key购买 nike

有以下模式用于在引发事件时避免竞争条件,以防另一个线程取消订阅 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 委托(delegate)分配给“处理程序”变量,然后一旦有人更改 MyEvent,“处理程序”引用的对象也会更改。

显然,情况并非如此,否则这个漂亮的小模式将无法工作。

我已经查看了 .NET 源代码,但仍然无法在那里找到我的答案(它可能在那里,但我已经找了大约一个小时但找不到,所以我来了。)我还阅读了 C# 语言规范关于事件和委托(delegate)的内容,但它没有解决这个问题。

感谢您的宝贵时间。

最佳答案

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.

虽然您认为委托(delegate)类型是引用类型是正确的,但它们是不可变 引用类型。来自 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.


另一方面,此模式解决的唯一问题是防止尝试调用空委托(delegate)引用。事件是prone to races尽管有这个“修复”。

关于c# - .NET:EventHandler 竞争条件修复如何工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4892802/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com