Я взаимодействую с серверной системой, где у меня никогда не должно быть более одного открытого соединения с данным объектом (идентифицируемый его числовым идентификатором), но разные потребители могут открывать и закрывать их независимо друг от друга.
Грубо говоря, у меня есть фрагмент фабричного класса, подобный этому:
private Dictionary<ulong, IFoo> _openItems = new Dictionary<ulong, IFoo>();
private object _locker = new object();
public IFoo Open(ulong id)
{
lock (_locker)
{
if (!_openItems.ContainsKey(id))
{
_openItems[id] = _nativeResource.Open(id);
}
_openItems[id].RefCount++;
return _openItems[id];
}
}
public void Close(ulong id)
{
lock (_locker)
{
if (_openItems.ContainsKey(id))
{
_openItems[id].RefCount--;
if (_openItems[id].RefCount == 0)
{
_nativeResource.Close(id);
_openItems.Remove(id);
}
}
}
}
Теперь вот проблема.В моем случае _nativeResource.Open работает очень медленно.Блокировка здесь довольно наивна и может быть очень медленной, когда существует много разных одновременных .Open вызовов, даже если они (скорее всего) ссылаются на разные идентификаторы и не перекрываются, особенно если их нет в _openItemsкеш.
Как структурировать блокировку так, чтобы я только предотвращал одновременный доступ к определенному идентификатору , а не ко всем вызывающим абонентам?