/// <summary> /// Decrements the refcount for the given item. Releases the item if its refcount reaches zero. /// </summary> /// <remarks>This method is thread-safe.</remarks> /// <param name="item">The item to release.</param> public void Release([CanBeNull] TItem item) { if (ReferenceEquals(item, null)) { return; } ItemRefCount itemRef; if (_refs.TryGetValue(item, out itemRef)) { lock (itemRef) { if (itemRef.Count > 0) { itemRef.Dec(); Decremented.Call(item); ItemRefCount removedRef; if (itemRef.IsZero() && _refs.TryRemove(item, out removedRef)) { Released.Call(item); } } } } }
/// <summary> Sets refcount to zero for all retained items and releases them. </summary> /// <remarks>This method is thread-safe.</remarks> public void Clear() { foreach (var refKvp in _refs) { ItemRefCount itemRef; if (_refs.TryRemove(refKvp.Key, out itemRef)) { itemRef.SetToZero(); Decremented.Call(refKvp.Key); Released.Call(refKvp.Key); } } }