/// <summary> /// Gets a lock for an object (discriminated by the provided 'key' param), which can be shared by other objects that call this extension method. /// To release the lock, the caller must call Dispose on the returned object. /// </summary> /// <remarks> /// The lock context returned is guaranteed to be the same reference if two or more objects (with equivalent keys) /// call this method 'at the same time'. The lock context is not guaranteed to be the same between calls if requests to GetLock are executed /// serially with no concurrent calls with the same key. /// Does not lock on the key. /// </remarks> /// <param name="key">A unique key to create a lock for</param> /// <returns>A lock unique to the specified key value</returns> public static IDisposable GetLock(string key) { LockObject @lock = null; do { if (@lock != null) { @lock.Dispose(); } @lock = new LockObject(key, LockManager.Locks, LockManager.Locks.GetOrAdd(key, _ => new LockState())); @lock.Acquire(); } while ([email protected]); return(@lock); }