Disposable
Provides implementation of dispose pattern.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Threading;
using System.Threading.Tasks;
namespace DotNext
{
[NullableContext(1)]
[Nullable(0)]
public abstract class Disposable : IDisposable
{
private const int NotDisposedState = 0;
private const int DisposingState = 1;
private const int DisposedState = 2;
private volatile int state;
protected bool IsDisposed => state == 2;
[EditorBrowsable(EditorBrowsableState.Advanced)]
protected bool IsDisposing {
get {
return state == 1;
}
}
[EditorBrowsable(EditorBrowsableState.Advanced)]
protected bool IsDisposingOrDisposed {
get {
return state != 0;
}
}
private string ObjectName => GetType().Name;
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
protected Task DisposedTask {
get {
return Task.FromException(new ObjectDisposedException(ObjectName));
}
}
protected Task<T> GetDisposedTask<[Nullable(2)] T>()
{
return Task.FromException<T>(new ObjectDisposedException(ObjectName));
}
protected bool TrySetDisposedException<[Nullable(2)] T>(TaskCompletionSource<T> source)
{
return source.TrySetException((Exception)new ObjectDisposedException(ObjectName));
}
protected bool TrySetDisposedException(TaskCompletionSource source)
{
return source.TrySetException(new ObjectDisposedException(ObjectName));
}
protected virtual void Dispose(bool disposing)
{
state = 2;
}
protected virtual ValueTask DisposeAsyncCore()
{
Dispose(true);
return ValueTask.CompletedTask;
}
[AsyncStateMachine(typeof(<DisposeAsyncImpl>d__19))]
private ValueTask DisposeAsyncImpl()
{
<DisposeAsyncImpl>d__19 stateMachine = default(<DisposeAsyncImpl>d__19);
stateMachine.<>t__builder = AsyncValueTaskMethodBuilder.Create();
stateMachine.<>4__this = this;
stateMachine.<>1__state = -1;
stateMachine.<>t__builder.Start(ref stateMachine);
return stateMachine.<>t__builder.Task;
}
protected ValueTask DisposeAsync()
{
switch (Interlocked.CompareExchange(ref state, 1, 0)) {
case 0:
return DisposeAsyncImpl();
case 1:
return DisposeAsyncCore();
default:
return ValueTask.CompletedTask;
}
}
[EditorBrowsable(EditorBrowsableState.Advanced)]
protected bool TryBeginDispose()
{
return Interlocked.CompareExchange(ref state, 1, 0) == 0;
}
public void Dispose()
{
Dispose(TryBeginDispose());
GC.SuppressFinalize(this);
}
public static void Dispose([Nullable(new byte[] {
1,
2
})] IEnumerable<IDisposable> objects)
{
foreach (IDisposable object in objects) {
object?.Dispose();
}
}
[AsyncStateMachine(typeof(<DisposeAsync>d__24))]
public static ValueTask DisposeAsync([Nullable(new byte[] {
1,
2
})] IEnumerable<IAsyncDisposable> objects)
{
<DisposeAsync>d__24 stateMachine = default(<DisposeAsync>d__24);
stateMachine.<>t__builder = AsyncValueTaskMethodBuilder.Create();
stateMachine.objects = objects;
stateMachine.<>1__state = -1;
stateMachine.<>t__builder.Start(ref stateMachine);
return stateMachine.<>t__builder.Task;
}
public static void Dispose([Nullable(new byte[] {
0,
2
})] ReadOnlySpan<IDisposable> objects)
{
ReadOnlySpan<IDisposable> readOnlySpan = objects;
for (int i = 0; i < readOnlySpan.Length; i++) {
readOnlySpan[i]?.Dispose();
}
}
public static ValueTask DisposeAsync([Nullable(new byte[] {
1,
2
})] params IAsyncDisposable[] objects)
{
return DisposeAsync(objects.AsEnumerable());
}
~Disposable()
{
Dispose(false);
}
}
}