//using System.Collections.Concurrent; //namespace Kit.Helpers //{ // /// Сервис для синхронизации потоков по ключу на основе словаря в памяти приложения // /// ключ синхронизации // public sealed class MemoryLockDictionaryService : ILockDictionaryService // { // private readonly ConcurrentDictionary _lockObjects = new ConcurrentDictionary(); // private readonly TimeSpan _cleanupInterval = TimeSpan.FromSeconds(45); // private readonly TimeSpan _expirationTime = TimeSpan.FromSeconds(10); // private const int _refreshIntervalMs = 100; // private struct LockValue // { // public object LockObject { get; } // public DateTime DateStart { get; private set; } // public LockValue() // { // LockObject = new object(); // DateStart = DateTime.UtcNow; // } // public void UpdateDate() => DateStart = DateTime.UtcNow; // } // public MemoryLockDictionaryService() // { // StartCleanupTask(); // } // private string GetTypeMask(string type) => $"$t${(type ?? "no_type")}$t$"; // private string GetKeyMask(string key) => $"$k${(key ?? "no_key")}$k$"; // private string GetLockKey(string type, string key) => $"{GetTypeMask(type)}_{GetKeyMask(key)}"; // public int GetLockCount(string type) // { // return _lockObjects.Count(x => x.Key.StartsWith(GetTypeMask(type))); // } // public int GetLockCount(string type, string key) // { // return _lockObjects.Count(x => x.Key.Equals(GetLockKey(type, key))); // } // public void ExecuteOnLock(string type, string key, Action action) // { // if (type == null) // { // throw new ArgumentNullException(nameof(type)); // } // if (key == null) // { // throw new ArgumentNullException(nameof(key)); // } // if (action == null) // { // throw new ArgumentNullException(nameof(action)); // } // string lockKey = GetLockKey(type, key); // var lockObject = GetOrCreateLockObject(key); // lock (lockObject) // { // // Периодически обновляя дату начала блокировки, выполняем операцию // using (var timer = new Timer(_ => UpdateLastAccess(key), null, 0, _refreshIntervalMs)) // { // action(); // } // } // } // public TResult ExecuteOnLock(string type, string key, Func action) // { // if (type == null) // { // throw new ArgumentNullException(nameof(type)); // } // if (key == null) // { // throw new ArgumentNullException(nameof(key)); // } // if (action == null) // { // throw new ArgumentNullException(nameof(action)); // } // string lockKey = GetLockKey(type, key); // var lockObject = GetOrCreateLockObject(key); // lock (lockObject) // { // // Периодически обновляя дату начала блокировки, выполняем операцию // using (var timer = new Timer(_ => UpdateLastAccess(key), null, 0, _refreshIntervalMs)) // { // return action(); // } // } // } // private object GetOrCreateLockObject(string key) // { // return _lockObjects.GetOrAdd(key, _ => new LockValue()).LockObject; // } // private void UpdateLastAccess(string key) // { // if (_lockObjects.TryGetValue(key, out var value)) // _lockObjects[key].UpdateDate(); // } // private void StartCleanupTask() // { // Task.Run(async () => // { // while (true) // { // await Task.Delay(_cleanupInterval); // CleanupExpiredLocks(); // } // }); // } // private void CleanupExpiredLocks() // { // var now = DateTime.UtcNow; // foreach (var key in _lockObjects.Keys) // { // if (_lockObjects.TryGetValue(key, out var value) && now - value.DateStart > _expirationTime) // { // _lockObjects.TryRemove(key, out _); // } // } // } // } //}