#nullable enable using System; using System.Collections.Concurrent; namespace BTCPayServer { public class ResourceTracker where T: notnull { public class ScopedResourceTracker : IDisposable { private ResourceTracker _parent; public ScopedResourceTracker(ResourceTracker resourceTracker) { _parent = resourceTracker; } ConcurrentDictionary _Scoped = new(); public bool TryTrack(T resource) { if (!_parent._TrackedResources.TryAdd(resource, string.Empty)) return false; _Scoped.TryAdd(resource, string.Empty); return true; } public bool Contains(T resource) => _Scoped.ContainsKey(resource); public void Dispose() { foreach (var d in _Scoped) _parent._TrackedResources.TryRemove(d.Key, out _); } } internal ConcurrentDictionary _TrackedResources = new(); public ScopedResourceTracker StartTracking() => new ScopedResourceTracker(this); public bool Contains(T resource) => _TrackedResources.ContainsKey(resource); } }