<PackageReference Include="System.Reactive" Version="4.4.1" />

StableCompositeDisposable

Represents a group of disposable resources that are disposed together.
using System.Collections.Generic; using System.Threading; namespace System.Reactive.Disposables { public abstract class StableCompositeDisposable : ICancelable, IDisposable { private sealed class Binary : StableCompositeDisposable { private IDisposable _disposable1; private IDisposable _disposable2; public override bool IsDisposed => Disposable.GetIsDisposed(ref _disposable1); public Binary(IDisposable disposable1, IDisposable disposable2) { Volatile.Write(ref _disposable1, disposable1); Volatile.Write(ref _disposable2, disposable2); } public override void Dispose() { Disposable.TryDispose(ref _disposable1); Disposable.TryDispose(ref _disposable2); } } private sealed class NAryEnumerable : StableCompositeDisposable { private volatile List<IDisposable> _disposables; public override bool IsDisposed => _disposables == null; public NAryEnumerable(IEnumerable<IDisposable> disposables) { _disposables = new List<IDisposable>(disposables); if (_disposables.Contains(null)) throw new ArgumentException(Strings_Core.DISPOSABLES_CANT_CONTAIN_NULL, "disposables"); } public override void Dispose() { List<IDisposable> list = Interlocked.Exchange(ref _disposables, null); if (list != null) { foreach (IDisposable item in list) { item.Dispose(); } } } } private sealed class NAryArray : StableCompositeDisposable { private IDisposable[] _disposables; public override bool IsDisposed => Volatile.Read(ref _disposables) == null; public NAryArray(IDisposable[] disposables) { int num = disposables.Length; IDisposable[] array = new IDisposable[num]; Array.Copy(disposables, 0, array, 0, num); if (Array.IndexOf(array, null) != -1) throw new ArgumentException(Strings_Core.DISPOSABLES_CANT_CONTAIN_NULL, "disposables"); Volatile.Write(ref _disposables, array); } public override void Dispose() { IDisposable[] array = Interlocked.Exchange(ref _disposables, null); if (array != null) { IDisposable[] array2 = array; for (int i = 0; i < array2.Length; i++) { array2[i].Dispose(); } } } } private sealed class NAryTrustedArray : StableCompositeDisposable { private IDisposable[] _disposables; public override bool IsDisposed => Volatile.Read(ref _disposables) == null; public NAryTrustedArray(IDisposable[] disposables) { Volatile.Write(ref _disposables, disposables); } public override void Dispose() { IDisposable[] array = Interlocked.Exchange(ref _disposables, null); if (array != null) { IDisposable[] array2 = array; for (int i = 0; i < array2.Length; i++) { array2[i].Dispose(); } } } } public abstract bool IsDisposed { get; } public static ICancelable Create(IDisposable disposable1, IDisposable disposable2) { if (disposable1 == null) throw new ArgumentNullException("disposable1"); if (disposable2 == null) throw new ArgumentNullException("disposable2"); return new Binary(disposable1, disposable2); } public static ICancelable Create(params IDisposable[] disposables) { if (disposables == null) throw new ArgumentNullException("disposables"); return new NAryArray(disposables); } internal static ICancelable CreateTrusted(params IDisposable[] disposables) { return new NAryTrustedArray(disposables); } public static ICancelable Create(IEnumerable<IDisposable> disposables) { if (disposables == null) throw new ArgumentNullException("disposables"); return new NAryEnumerable(disposables); } public abstract void Dispose(); } }