Disposable
Provides a set of static methods for creating IDisposable objects.
using System.Threading;
namespace System.Reactive.Disposables
{
public static class Disposable
{
private sealed class EmptyDisposable : IDisposable
{
public static readonly EmptyDisposable Instance = new EmptyDisposable();
private EmptyDisposable()
{
}
public void Dispose()
{
}
}
public static IDisposable Empty => EmptyDisposable.Instance;
public static IDisposable Create(Action dispose)
{
if (dispose == null)
throw new ArgumentNullException("dispose");
return new AnonymousDisposable(dispose);
}
public static IDisposable Create<TState>(TState state, Action<TState> dispose)
{
if (dispose == null)
throw new ArgumentNullException("dispose");
return new AnonymousDisposable<TState>(state, dispose);
}
internal static IDisposable GetValue(ref IDisposable fieldRef)
{
IDisposable disposable = Volatile.Read(ref fieldRef);
if (disposable != BooleanDisposable.True)
return disposable;
return null;
}
internal static IDisposable GetValueOrDefault(ref IDisposable fieldRef)
{
IDisposable disposable = Volatile.Read(ref fieldRef);
if (disposable != BooleanDisposable.True)
return disposable;
return EmptyDisposable.Instance;
}
internal static bool SetSingle(ref IDisposable fieldRef, IDisposable value)
{
TrySetSingleResult num = TrySetSingle(ref fieldRef, value);
if (num == TrySetSingleResult.AlreadyAssigned)
throw new InvalidOperationException(Strings_Core.DISPOSABLE_ALREADY_ASSIGNED);
return num == TrySetSingleResult.Success;
}
internal static TrySetSingleResult TrySetSingle(ref IDisposable fieldRef, IDisposable value)
{
IDisposable disposable = Interlocked.CompareExchange(ref fieldRef, value, null);
if (disposable == null)
return TrySetSingleResult.Success;
if (disposable != BooleanDisposable.True)
return TrySetSingleResult.AlreadyAssigned;
value?.Dispose();
return TrySetSingleResult.Disposed;
}
internal static bool TrySetMultiple(ref IDisposable fieldRef, IDisposable value)
{
IDisposable disposable = Volatile.Read(ref fieldRef);
while (true) {
if (disposable == BooleanDisposable.True) {
value?.Dispose();
return false;
}
IDisposable disposable2 = Interlocked.CompareExchange(ref fieldRef, value, disposable);
if (disposable == disposable2)
break;
disposable = disposable2;
}
return true;
}
internal static bool TrySetSerial(ref IDisposable fieldRef, IDisposable value)
{
IDisposable disposable = Volatile.Read(ref fieldRef);
while (true) {
if (disposable == BooleanDisposable.True) {
value?.Dispose();
return false;
}
IDisposable disposable2 = Interlocked.CompareExchange(ref fieldRef, value, disposable);
if (disposable2 == disposable)
break;
disposable = disposable2;
}
disposable?.Dispose();
return true;
}
internal static bool GetIsDisposed(ref IDisposable fieldRef)
{
return Volatile.Read(ref fieldRef) == BooleanDisposable.True;
}
internal static bool TryDispose(ref IDisposable fieldRef)
{
IDisposable disposable = Interlocked.Exchange(ref fieldRef, BooleanDisposable.True);
if (disposable == BooleanDisposable.True)
return false;
disposable?.Dispose();
return true;
}
internal static bool TryRelease<TState>(ref IDisposable fieldRef, TState state, Action<IDisposable, TState> disposeAction)
{
IDisposable disposable = Interlocked.Exchange(ref fieldRef, BooleanDisposable.True);
if (disposable == BooleanDisposable.True)
return false;
disposeAction(disposable, state);
return true;
}
}
}