// 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.Reactive.Concurrency; using System.Threading; namespace System.Reactive.Disposables { /// /// Represents a disposable resource whose disposal invocation will be posted to the specified . /// public sealed class ContextDisposable : ICancelable { private volatile IDisposable _disposable; /// /// Initializes a new instance of the class that uses the specified on which to dispose the specified disposable resource. /// /// Context to perform disposal on. /// Disposable whose Dispose operation to run on the given synchronization context. /// or is null. public ContextDisposable(SynchronizationContext context, IDisposable disposable) { Context = context ?? throw new ArgumentNullException(nameof(context)); _disposable = disposable ?? throw new ArgumentNullException(nameof(disposable)); } /// /// Gets the provided . /// public SynchronizationContext Context { get; } /// /// Gets a value that indicates whether the object is disposed. /// public bool IsDisposed => _disposable == BooleanDisposable.True; /// /// Disposes the underlying disposable on the provided . /// public void Dispose() { var old = Interlocked.Exchange(ref _disposable, BooleanDisposable.True); if (old != BooleanDisposable.True) { Context.PostWithStartComplete(static d => d.Dispose(), old); } } } }