namespace Kit.Helpers { public interface ILockService { TResult Lock(TKey lockKey, Func action); void Lock(TKey lockKey, Action action); } public class LockService : ILockService { private object _lockObjectLock = new object(); private IDictionary _lockObjects = new Dictionary(); /// Блокировка операции по ключу /// Ключ для блокировки /// Выполняемая операция public TResult Lock(TKey lockKey, Func action) { try { lock (GetLockObject(lockKey)) { return action(); } } finally { RemoveLockObject(lockKey); } } /// Блокировка операции по ключу /// Ключ для блокировки /// Выполняемая операция public void Lock(TKey lockKey, Action action) { try { lock (GetLockObject(lockKey)) { action(); } } finally { RemoveLockObject(lockKey); } } /// Получение объекта для блокировки по ключу /// Ключ для блокировки /// Объект блокировки, соответствующий ключу private object GetLockObject(TKey lockKey) { lock (_lockObjectLock) { if (_lockObjects.ContainsKey(lockKey) == false) { _lockObjects.Add(lockKey, new object()); } return _lockObjects[lockKey]; } } /// Удаление объекта блокировки, соответствующего ключу /// Ключ для блокировки private void RemoveLockObject(TKey lockKey) { /// дожидаемся освобождения объекта lock (this.GetLockObject(lockKey)) { } /// удаляем объект блокировки из очереди lock (_lockObjectLock) { _lockObjects.Remove(lockKey); } } } }