73 lines
2.1 KiB
C#
73 lines
2.1 KiB
C#
namespace Kit.Helpers
|
|
{
|
|
/// <summary>Сервис для синхронизации потоков по ключу на основе словаря в памяти приложения</summary>
|
|
/// <typeparam name="TKey">ключ синхронизации</typeparam>
|
|
public class MemoryLockDictionaryService<TKey>: ILockDictionaryService<TKey> where TKey : notnull
|
|
{
|
|
private object _lockObjectLock;
|
|
private IDictionary<TKey, object> _lockObjects;
|
|
|
|
public MemoryLockDictionaryService()
|
|
{
|
|
_lockObjectLock = new object();
|
|
_lockObjects = new Dictionary<TKey, object>();
|
|
}
|
|
|
|
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); }
|
|
}
|
|
|
|
public void ExecuteOnLock(TKey lockKey, Action action)
|
|
{
|
|
try
|
|
{
|
|
lock (GetLockObject(lockKey))
|
|
{
|
|
action();
|
|
}
|
|
RemoveLockObject(lockKey);
|
|
}
|
|
catch
|
|
{
|
|
throw;
|
|
}
|
|
finally
|
|
{
|
|
}
|
|
}
|
|
|
|
public TResult ExecuteOnLock<TResult>(TKey lockKey, Func<TResult> action)
|
|
{
|
|
try
|
|
{
|
|
lock (GetLockObject(lockKey))
|
|
{
|
|
return action();
|
|
}
|
|
}
|
|
catch
|
|
{
|
|
throw;
|
|
}
|
|
finally
|
|
{
|
|
RemoveLockObject(lockKey);
|
|
}
|
|
}
|
|
}
|
|
}
|