Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does GetOrAdd wait if it's busy on retrieving a value with same key?

Consider this code:

void DoSomething(int key)
{
    concurrentDictionary.GetOrAdd(key, (k)=>
        {
            //Do some expensive over network and database to retrieve value.
        });

Consider 2 threads are invoking DoSomething(2). At the same time they will see that there's no item with Key==2 in the dictionary. Consider Thread1 starts doing the expensive algorithm to retrieve the value of 2.

Question 1: Will Thread2 waits for Thread1 to accomplish its job? Or simply tries to retrieve the value itself, and throwing it away at the time of adding it to the dictionary? (As the Thread1 added this already )

Question 2: If Thread2 doesn't wait, what's the best solution to avoid multiple running of that expensive algorithm?

like image 848
mehrandvd Avatar asked Feb 05 '14 08:02

mehrandvd


1 Answers

It tells you in the documentation:

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.

For question 2, I'd consider changing from a ConcurrentDictionary<int,Something> to a ConcurrentDictionary<int,Lazy<Something>> where the addValueFactory method simply constructs a Lazy<Something> that specifies the ExecutionAndPublication mode. The expensive operation would then by the valueFactory for the Lazy<Something>

like image 93
Damien_The_Unbeliever Avatar answered Oct 06 '22 00:10

Damien_The_Unbeliever