我注意到GetOrAdd()总是执行工厂委托(delegate),即使该值存在于字典中也是如此。例如:

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()方法始终执行。这是预期的吗?我本以为如果键在字典中存在,则委托(delegate)方法将不会执行。

最佳答案

看到这种情况的原因是,您不是将CacheValueFactory作为委托(delegate)传递,而是迅速评估函数并传递结果值。这会导致您使用接受键和值的重载,而不是接受键和委托(delegate)的重载。

要使用委托(delegate)版本,请将代码切换到以下代码

string val = _cache.GetOrAdd(key, CacheValueFactory);

关于c# - ConcurrentDictionary.GetOrAdd始终执行委托(delegate)方法,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/4400262/

10-17 02:14