#if !NET_4_6 using System; namespace LinqInternal.Threading { public sealed partial class Disposable : IDisposable { private int _status; [System.Diagnostics.DebuggerNonUserCode] ~Disposable() { try { // Empty } finally { try { Dispose(false); } catch (Exception exception) { // Catch'em all - fields may be partially collected. GC.KeepAlive(exception); } } } public bool IsDisposed { [System.Diagnostics.DebuggerNonUserCode] get { return _status == -1; } } [System.Diagnostics.DebuggerNonUserCode] public void Dispose() { try { Dispose(true); } finally { GC.SuppressFinalize(this); } } [System.Diagnostics.DebuggerNonUserCode] public void DisposedConditional(Action whenDisposed, Action whenNotDisposed) { if (_status == -1) { if (!ReferenceEquals(whenDisposed, null)) { whenDisposed.Invoke(); } } else { if (!ReferenceEquals(whenNotDisposed, null)) { if (ThreadingHelper.SpinWaitRelativeSet(ref _status, 1, -1)) { try { whenNotDisposed.Invoke(); } finally { System.Threading.Interlocked.Decrement(ref _status); } } else { if (!ReferenceEquals(whenDisposed, null)) { whenDisposed.Invoke(); } } } } } [System.Diagnostics.DebuggerNonUserCode] public TReturn DisposedConditional(Func whenDisposed, Func whenNotDisposed) { if (_status == -1) { if (ReferenceEquals(whenDisposed, null)) { return default(TReturn); } else { return whenDisposed.Invoke(); } } else { if (ReferenceEquals(whenNotDisposed, null)) { return default(TReturn); } else { if (ThreadingHelper.SpinWaitRelativeSet(ref _status, 1, -1)) { try { return whenNotDisposed.Invoke(); } finally { System.Threading.Interlocked.Decrement(ref _status); } } else { if (ReferenceEquals(whenDisposed, null)) { return default(TReturn); } else { return whenDisposed.Invoke(); } } } } } [System.Diagnostics.DebuggerNonUserCode] private void Dispose(bool disposeManagedResources) { GC.KeepAlive(disposeManagedResources); if (TakeDisposalExecution()) { try { _release.Invoke(); } finally { _release = null; } } } private bool TakeDisposalExecution() { return _status != -1 && ThreadingHelper.SpinWaitSetUnless(ref _status, -1, 0, -1); } } } #endif