4

I have used the lock statement in C# to exclusively execute a piece of code. Is there a way to do same based on a key.

for e.g.:

lock(object, key)
{
//code-here
}

I have a method which has some piece of code that is not thread-safe, but only if the key (string) happens to be same in two parallel executions. Is there a way to somehow accomplish this in .NET ?

If there is a way then we can have parallel executions if the key being used in the parallel executions is different and could improve performance.

Brij
  • 11,731
  • 22
  • 78
  • 116

2 Answers2

6

Put lock objects into dictionary indexed by the key - Dictionary<string, object> and grab objects by key to lock.

If you need to dynamically add new key/lock object pairs make sure to lock around the dictionary access, otherwise if after construction you only read values from dictionary no additional locking is needed.

Alexei Levenkov
  • 98,904
  • 14
  • 127
  • 179
  • 5
    In regards to your 2nd paragraph, you could use `ConcurrentDictionary` if that was necessary. – Matthew Jun 17 '15 at 04:24
3

I create a library called AsyncKeyedLock which solves the problem. Internally it uses a ConcurrentDictionary and SemaphoreSlim objects.

In case you're using asynchronous code you can use:

using (await _locker.LockAsync(myObject.Id))
{
   ...
}

or if you're using synchronous code:

using (_locker.Lock(myObject.Id))
{
   ...
}
Mark Cilia Vincenti
  • 1,410
  • 8
  • 25
  • 1
    Thanks for this. Was just thinking I don't want to spend the time writing the code to manage the ConcurrentDictionary of object locks, which, in my case, would otherwise grow pretty big :) – Remi Despres-Smyth May 04 '23 at 19:18