Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Locking based on parameters

Suppose I have this method:

void Foo(int bar)
{
    // do stuff
}

Here is the behavior I want Foo to have:

  1. If thread 1 calls Foo(1) and thread 2 calls Foo(2), both threads can run concurrently.

  2. If thread 1 calls Foo(1) and thread 2 calls Foo(1), both threads cannot run concurrently.

Is there a good, standard way in .net to specify this type of behavior? I have a solution that uses a dictionary of objects to lock on, but that feels kind of messy.

like image 330
Bradley Avatar asked Jun 23 '11 15:06

Bradley


3 Answers

Use a dictionary that provides different lock objects for the different arguments. Set up the dictionary when you instantiate the underlying object (or statically, if applicable):

var locks = new Dictionary<int, object>() {
    {1, new Object()},
    {2, new Object()},
    …
};

And then use it inside your method:

void Foo(int bar) {
    lock (locks[bar]) {
        …
    }
}

I wouldn’t say that this solution is messy, on the contrary: providing a fine lock granularity is commendable and since locks on value types don’t work in .NET, having a mapping is the obvious solution.

Be careful though: the above only works as long as the dictionary isn’t concurrently modified and read. It is therefore best to treat the dictionary as read-only after its set-up.

like image 53
Konrad Rudolph Avatar answered Nov 16 '22 23:11

Konrad Rudolph


Bottom line: you can't lock on value types.

The dictionary you're using is the best approach I can think of. It's kludgey, but it works.

Personally, I'd pursue an architectural solution that makes the locking unnecessary, but I don't know enough about your system to give you pointers there.

like image 21
Randolpho Avatar answered Nov 17 '22 01:11

Randolpho


Using Dictionary is not enough, you should use "ConcurrentDictionary" or implement a data structure that supports multi-thread access.

like image 2
Meital Krengel Avatar answered Nov 17 '22 00:11

Meital Krengel