<PackageReference Include="Relativity.Transfer.Client" Version="7.1.40" />

RefCountDisposable

public sealed class RefCountDisposable : ICancelable, IDisposable
using System.Threading; namespace System.Reactive.Disposables { public sealed class RefCountDisposable : ICancelable, IDisposable { private sealed class InnerDisposable : IDisposable { private RefCountDisposable _parent; public InnerDisposable(RefCountDisposable parent) { _parent = parent; } public void Dispose() { Interlocked.Exchange(ref _parent, null)?.Release(); } } private readonly bool _throwWhenDisposed; private readonly object _gate = new object(); private IDisposable _disposable; private bool _isPrimaryDisposed; private int _count; public bool IsDisposed => _disposable == null; public RefCountDisposable(IDisposable disposable) : this(disposable, false) { } public RefCountDisposable(IDisposable disposable, bool throwWhenDisposed) { if (disposable == null) throw new ArgumentNullException("disposable"); _disposable = disposable; _isPrimaryDisposed = false; _count = 0; _throwWhenDisposed = throwWhenDisposed; } public IDisposable GetDisposable() { lock (_gate) { if (_disposable != null) { _count++; return new InnerDisposable(this); } if (_throwWhenDisposed) throw new ObjectDisposedException("RefCountDisposable"); return Disposable.Empty; } } public void Dispose() { IDisposable disposable = null; lock (_gate) { if (_disposable != null && !_isPrimaryDisposed) { _isPrimaryDisposed = true; if (_count == 0) { disposable = _disposable; _disposable = null; } } } disposable?.Dispose(); } private void Release() { IDisposable disposable = null; lock (_gate) { if (_disposable != null) { _count--; if (_isPrimaryDisposed && _count == 0) { disposable = _disposable; _disposable = null; } } } disposable?.Dispose(); } } }