Update: It is acceptable if this method is not thread safe, but I\'m interested in learning how I would make it thread safe. Also, I do not want to lock on
I added a solution in Bardock.Utils package inspired by @eugene-beresovsky answer.
Usage:
private static LockeableObjectFactory _lockeableStringFactory =
new LockeableObjectFactory();
string key = ...;
lock (_lockeableStringFactory.Get(key))
{
...
}
Solution code:
namespace Bardock.Utils.Sync
{
///
/// Creates objects based on instances of TSeed that can be used to acquire an exclusive lock.
/// Instanciate one factory for every use case you might have.
/// Inspired by Eugene Beresovsky's solution: https://stackoverflow.com/a/19375402
///
/// Type of the object you want lock on
public class LockeableObjectFactory
{
private readonly ConcurrentDictionary _lockeableObjects = new ConcurrentDictionary();
///
/// Creates or uses an existing object instance by specified seed
///
///
/// The object used to generate a new lockeable object.
/// The default EqualityComparer is used to determine if two seeds are equal.
/// The same object instance is returned for equal seeds, otherwise a new object is created.
///
public object Get(TSeed seed)
{
return _lockeableObjects.GetOrAdd(seed, valueFactory: x => new object());
}
}
}