gpt4 book ai didi

c# - 并发字典中的 valueFactory

转载 作者:太空宇宙 更新时间:2023-11-03 10:23:54 25 4
gpt4 key购买 nike

我正在编写一个 winform 程序来测试具有以下类的 C# 并发字典:

public class Class1
{
public int X = 10;

public Class1(int x)
{
X = x;
Debug.WriteLine("Class1 Created");
}
}

和下面的按钮代码:

  private void button1_Click(object sender, EventArgs e)
{
var dict = new ConcurrentDictionary<int, Class1>();

Func<Class1> valueFactory = () =>
{
Debug.WriteLine("Factory Called");
return new Class1(5);
};

var temp = dict.GetOrAdd(1, valueFactory());
Debug.WriteLine(temp.X);
temp.X = 20;

var temp2 = dict.GetOrAdd(1, valueFactory());
Debug.WriteLine(temp2.X);
}

我注意到 valueFactory 方法总是被执行,并且 Class1 构造函数被调用两次,即使在第一个 GetorAdd 方法之后键已经存在于字典中。

但是,如果我将 Func 定义更改为

Func<int, Class1> valueFactory = (k) => 
{
Debug.WriteLine("Factory Called");
return new Class1(5);
};

然后像下面这样调用 GetorAdd 方法:

var temp = dict.GetOrAdd(1, valueFactory);

程序以预期的方式工作,因为它在第二次调用中没有调用 Class1 构造函数。我怀疑这是因为我传递了一个委托(delegate) valueFactory 而不是函数调用 valueFactory()到 GetorAdd 方法。我想知道是否有关于引擎盖下发生的事情的详细解释,我也不明白为什么如果我的 Func 定义不是 Func<int, Class1,我不能不将 valueFactory 作为委托(delegate)传递。 (与字典定义相同)

谢谢。

最佳答案

当你这样做时:

var temp = dict.GetOrAdd(1, valueFactory());
...
var temp2 = dict.GetOrAdd(1, valueFactory());

您实际上是在调用 valueFactory 调用dict.GetOrAdd()之前.所以每次都被调用是正常的。当然,Class1 的新实例第二次调用返回到 valueFactory()最终没有用,但它还是被创建了。

相反,当您这样做时:

var temp = dict.GetOrAdd(1, valueFactory);
...
var temp2 = dict.GetOrAdd(1, valueFactory);

...您实际上正在使用方法的不同重载 GetOrAdd ,您将引用传递给委托(delegate) valueFactory无需自己调用它。 GetOrAdd()然后方法决定是否需要调用 valueFactory或不基于键是否在字典中找到。

ConcurrentDictionary.GetOrAdd Method (TKey, Func)文档:

Adds a key/value pair to the ConcurrentDictionary<TKey, TValue> by using the specified function, if the key does not already exist.

在这种情况下,它不需要第二次调用它,因为它在您第二次调用 GetOrAdd() 时找到了 key 。 .


但是,请注意传入 valueFactory作为 GetOrAdd 的委托(delegate)不保证它不会被调用两次。在多线程场景中尤其如此。注意 ConcurrentDictionary.GetOrAdd Method (TKey, Func) 上的文档还谈到了这一点:

If you call GetOrAdd simultaneously on different threads, addValueFactory may be called multiple times, but its key/value pair might not be added to the dictionary for every call.

关于c# - 并发字典中的 valueFactory,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32334305/

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