1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798 |
- // Licensed to the .NET Foundation under one or more agreements.
- // The .NET Foundation licenses this file to you under the MIT License.
- // See the LICENSE file in the project root for more information.
- using System.Collections.Generic;
- using System.Threading;
- using System.Threading.Tasks;
- namespace System.Reactive.Disposables
- {
- public abstract class StableCompositeAsyncDisposable : IAsyncDisposable
- {
- public static StableCompositeAsyncDisposable Create(IAsyncDisposable disposable1, IAsyncDisposable disposable2)
- {
- if (disposable1 == null)
- throw new ArgumentNullException(nameof(disposable1));
- if (disposable2 == null)
- throw new ArgumentNullException(nameof(disposable2));
- return new Binary(disposable1, disposable2);
- }
- public static StableCompositeAsyncDisposable Create(params IAsyncDisposable[] disposables)
- {
- if (disposables == null)
- throw new ArgumentNullException(nameof(disposables));
- return new NAry(disposables);
- }
- public static StableCompositeAsyncDisposable Create(IEnumerable<IAsyncDisposable> disposables)
- {
- if (disposables == null)
- throw new ArgumentNullException(nameof(disposables));
- return new NAry(disposables);
- }
- public abstract ValueTask DisposeAsync();
- private sealed class Binary : StableCompositeAsyncDisposable
- {
- private volatile IAsyncDisposable _disposable1;
- private volatile IAsyncDisposable _disposable2;
- public Binary(IAsyncDisposable disposable1, IAsyncDisposable disposable2)
- {
- _disposable1 = disposable1;
- _disposable2 = disposable2;
- }
- public override async ValueTask DisposeAsync()
- {
- var d1 = Interlocked.Exchange(ref _disposable1, null);
- if (d1 != null)
- {
- await d1.DisposeAsync().ConfigureAwait(false);
- }
- var d2 = Interlocked.Exchange(ref _disposable2, null);
- if (d2 != null)
- {
- await d2.DisposeAsync().ConfigureAwait(false);
- }
- }
- }
- private sealed class NAry : StableCompositeAsyncDisposable
- {
- private volatile List<IAsyncDisposable> _disposables;
- public NAry(IAsyncDisposable[] disposables)
- : this((IEnumerable<IAsyncDisposable>)disposables)
- {
- }
- public NAry(IEnumerable<IAsyncDisposable> disposables)
- {
- _disposables = new List<IAsyncDisposable>(disposables);
- }
- public override async ValueTask DisposeAsync()
- {
- var old = Interlocked.Exchange(ref _disposables, null);
- if (old != null)
- {
- foreach (var d in old)
- {
- if (d != null)
- {
- await d.DisposeAsync().ConfigureAwait(false);
- }
- }
- }
- }
- }
- }
- }
|