Всем привет.
Подскажите — как можно оптимизировать следующий код?
Класс предоставляет локи для синхронизации операций в других Concurrent-коллекциях. Например, в ConcurrentDictionary для методов с отложенной инициализации AddOrUpdate и GetOrAdd.
Задача — получить объект блокировки (который SyncRoot) для определенного ключа (чтобы не блокировать всю коллекцию). Если больше никто эту блокировку не использует — убрать из коллекции. Идеально было бы вовсе отдать работу по подсчёту ссылок GC.
public sealed class ConcurrentLockProvider<TKey>
{
private readonly Dictionary<TKey, Lock> _locks;
public ConcurrentLockProvider()
: this(EqualityComparer<TKey>.Default)
{
}
public ConcurrentLockProvider(IEqualityComparer<TKey> comparer)
{
_locks = new Dictionary<TKey, Lock>(comparer);
}
public IDisposable Acquire(TKey key)
{
lock(_locks)
{
Lock item;
if(!_locks.TryGetValue(key, out item))
{
item = new Lock(key, _locks);
_locks[key] = item;
}
Interlocked.Increment(ref item.Counter);
return item;
}
}
private sealed class Lock : IDisposable
{
private readonly TKey _key;
private readonly Dictionary<TKey, Lock> _dic;
public long Counter;
public Lock(TKey key, Dictionary<TKey, Lock> locks)
{
_key = key;
_dic = locks;
}
#region Implementation of IDisposable
public void Dispose()
{
lock(_dic)
{
if(Interlocked.Decrement(ref Counter) < 1)
_dic.Remove(_key);
}
}
#endregion
}
}