可以递归调用ConcurrentDictionary.GetOrAdd()吗?

red*_*alx 5 .net concurrentdictionary

ConcurrentDictionary.GetOrAdd(TKey,Func <TKey,TValue>)接受一个工厂函数,允许将项目的延迟实例化放入字典中.

定义一个自己调用GetOrAdd()的工厂函数是安全的,即在'父'GetOrAdd()的上下文中调用GetOrAdd.

以下代码演示了该模式; 它确实有效,但它安全吗?

class Program
{
    static ConcurrentDictionary<string,object> __dict = new ConcurrentDictionary<string, object>();

    static void Main(string[] args)
    {
        Foo foo = GetOrAddFoo();
        Console.WriteLine(foo._name);
        Console.WriteLine(foo._bar._name);
        Console.ReadKey();
    }

    static Bar GetOrAddBar()
    {
        Console.WriteLine("GetOrAddBar: enter");
        Func<string,Bar> factoryFn = (x) => LoadBar(x);
        Bar bar = __dict.GetOrAdd("bar", factoryFn) as Bar;
        Console.WriteLine("GetOrAddBar: exit");
        return bar;
    }

    static Foo GetOrAddFoo()
    {
        Console.WriteLine("GetOrAddFoo: enter");
        Func<string,Foo> factoryFn = (x) => LoadFoo(x);
        Foo foo = __dict.GetOrAdd("foo", factoryFn) as Foo;
        Console.WriteLine("GetOrAddFoo: exit");
        return foo;
    }

    static Bar LoadBar(string name)
    {
        Bar bar =  new Bar();
        bar._name = name;
        return bar;
    }

    static Foo LoadFoo(string name)
    {
        Foo foo = new Foo();
        foo._name = name;
        foo._bar = GetOrAddBar();
        return foo;
    }

    public class Foo
    {
       public string _name;
       public Bar _bar;
    }

    public class Bar
    {
        public string _name;
    }
}
Run Code Online (Sandbox Code Playgroud)

jus*_*god -1

valueFactory 委托被调用并到达内部锁。(基于MSDN)

因此,只要您的委托很简单并且不访问任何非线程安全的内容,它就非常安全。我的意思是,如果你的方法只是创建一些类,那么就没有危险。如果您的方法将尝试读取类的某些字段或执行一些锁定,您可能必须考虑如何解决死锁问题。

我假设这个内部锁锁定在 __dict[key] 上