ConcurrentDictionary.GetOrAdd始终执行委托方法
问题描述:
我注意到GetOrAdd()始终执行工厂委托,即使该值存在于字典中。例如:ConcurrentDictionary.GetOrAdd始终执行委托方法
class Program
{
private static ConcurrentDictionary<string, string> _cache = new ConcurrentDictionary<string, string>();
static void Main(string[] args)
{
string value;
value = GetValueFromCache("A"); // cache is empty, CacheValueFactory executes, A is added
value = GetValueFromCache("A"); // cache contains A, CacheValueFactory executes
value = GetValueFromCache("C"); // cache contains A, CacheValueFactory, C is added
value = GetValueFromCache("A"); // cache contains A and C, CacheValueFactory executes
}
private static string GetValueFromCache(string key)
{
string val = _cache.GetOrAdd(key, CacheValueFactory(key));
return val;
}
private static string CacheValueFactory(string key)
{
if (key == "A")
return "Apple";
else if (key == "B")
return "Banana";
else if (key == "C")
return "Cherry";
return null;
}
}
第一次调用GetValueFromCache(“A”)时,缓存为空,并且A:Apple被添加。加入调试器,我注意到在对GetValueFromCache(“A”)的第二次和第三次调用中,CacheValueFactory()方法始终执行。这是预期的吗?如果密钥存在于字典中,我会认为委托方法不会执行。
答
你看到这个的原因是你没有通过CacheValueFactory
作为委托,而是立即评估函数并传递结果值。这会导致您使用接受键和值的重载,而不是接受键和委托的重载。
要使用代理的版本。如果你想处理稍微复杂场景的代码转换为以下
string val = _cache.GetOrAdd(key, CacheValueFactory);
答
,例如,当参数不匹配的钥匙,你可以使用lambda 。
var keyStr = string.Format("Something_{0}", key);
string val = _cache.GetOrAdd(keyStr,_ => CacheValueFactory(key));
Ooops。你是对的:) – Bullines 2010-12-09 16:05:40