Disposable
Provides a set of static methods for creating IDisposable objects.
using System.Diagnostics.CodeAnalysis;
using System.Runtime.CompilerServices;
using System.Threading;
namespace System.Reactive.Disposables
{
[System.Runtime.CompilerServices.NullableContext(2)]
[System.Runtime.CompilerServices.Nullable(0)]
public static class Disposable
{
[System.Runtime.CompilerServices.NullableContext(0)]
private sealed class EmptyDisposable : IDisposable
{
[System.Runtime.CompilerServices.Nullable(1)]
public static readonly EmptyDisposable Instance = new EmptyDisposable();
private EmptyDisposable()
{
}
public void Dispose()
{
}
}
[System.Runtime.CompilerServices.Nullable(1)]
public static IDisposable Empty {
[System.Runtime.CompilerServices.NullableContext(1)]
get {
return EmptyDisposable.Instance;
}
}
[System.Runtime.CompilerServices.NullableContext(1)]
public static IDisposable Create(Action dispose)
{
if (dispose == null)
throw new ArgumentNullException("dispose");
return new AnonymousDisposable(dispose);
}
[System.Runtime.CompilerServices.NullableContext(1)]
public static IDisposable Create<[System.Runtime.CompilerServices.Nullable(2)] TState>(TState state, Action<TState> dispose)
{
if (dispose == null)
throw new ArgumentNullException("dispose");
return new AnonymousDisposable<TState>(state, dispose);
}
internal static IDisposable GetValue([System.Diagnostics.CodeAnalysis.NotNullIfNotNull("fieldRef")] ref IDisposable fieldRef)
{
IDisposable disposable = Volatile.Read(ref fieldRef);
if (disposable != BooleanDisposable.True)
return disposable;
return null;
}
[return: System.Diagnostics.CodeAnalysis.NotNullIfNotNull("fieldRef")]
internal static IDisposable GetValueOrDefault([System.Diagnostics.CodeAnalysis.NotNullIfNotNull("fieldRef")] ref IDisposable fieldRef)
{
IDisposable disposable = Volatile.Read(ref fieldRef);
if (disposable != BooleanDisposable.True)
return disposable;
return EmptyDisposable.Instance;
}
internal static TrySetSingleResult TrySetSingle([System.Diagnostics.CodeAnalysis.NotNullIfNotNull("value")] 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([System.Diagnostics.CodeAnalysis.NotNullIfNotNull("value")] 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([System.Diagnostics.CodeAnalysis.NotNullIfNotNull("value")] 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 void Dispose([System.Diagnostics.CodeAnalysis.NotNullIfNotNull("fieldRef")] ref IDisposable fieldRef)
{
IDisposable disposable = Interlocked.Exchange(ref fieldRef, BooleanDisposable.True);
if (disposable != BooleanDisposable.True)
disposable?.Dispose();
}
}
}