使用具有数千甚至数百万条目的
ConcurrentDictionary<String, SemaphoreSlim>
仅锁定特定键是否合理?也就是说,像
private static readonly ConcurrentDictionary<String, SemaphoreSlim> _Locks = new();
...
var _Lock = _Locks.GetOrAdd(_Key, (_) => new SemaphoreSlim(1, 1));
await _Lock.WaitAsync();
try { ... } finally { _Lock.Release() }
我主要关心的是:
(_) => new SemaphoreSlim(1, 1)
可能被调用额外的时间,这样就有一些 SemaphoreSlims 被分配但最终从未使用过。拥有一个
ConcurrentDictionary<K,V>
和数以百万计的闲置 SemaphoreSlim
坐在一起肯定令人担忧。如果您有足够的可用内存,这可能没什么大不了的,但是如果您的目标是经济地使用资源,则可以从字典中驱逐目前未被积极使用的SemaphoreSlim
s。这不是微不足道的,因为您必须跟踪有多少工人在使用每个信号量,但这也不是火箭科学。您可以在这个问题中找到实现:
如果您担心
SemaphoreSlim
被遗弃,请看这个问题:
处置
IDisposable
实例原则上是正确的做法,但实际上 SemaphoreSlim.Dispose
方法是空操作,除非您使用很少使用的 AvailableWaitHandle
属性。