Suppose I have this method:
void Foo(int bar)
{
// do stuff
}
Here is the behavior I want Foo
to have:
If thread 1 calls Foo(1)
and thread 2 calls Foo(2)
, both threads can run concurrently.
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.
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.
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.
Using Dictionary is not enough, you should use "ConcurrentDictionary" or implement a data structure that supports multi-thread access.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With