From d1174f3f8979321a9182925df460e07e08157b41 Mon Sep 17 00:00:00 2001 From: Atsushi Eno Date: Tue, 13 Nov 2012 03:47:31 +0900 Subject: partial import of ca05fdeb565e: Reactive Extensions OSS V1.0 --- .../Reactive/Disposables/ScheduledDisposable.cs | 85 ++++++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 Rx.NET/System.Reactive.Core/Reactive/Disposables/ScheduledDisposable.cs (limited to 'Rx.NET/System.Reactive.Core/Reactive/Disposables/ScheduledDisposable.cs') diff --git a/Rx.NET/System.Reactive.Core/Reactive/Disposables/ScheduledDisposable.cs b/Rx.NET/System.Reactive.Core/Reactive/Disposables/ScheduledDisposable.cs new file mode 100644 index 0000000..eb742aa --- /dev/null +++ b/Rx.NET/System.Reactive.Core/Reactive/Disposables/ScheduledDisposable.cs @@ -0,0 +1,85 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +using System.Reactive.Concurrency; +using System.Threading; + +namespace System.Reactive.Disposables +{ + /// + /// Represents a disposable resource whose disposal invocation will be scheduled on the specified . + /// + public sealed class ScheduledDisposable : ICancelable + { + private readonly IScheduler _scheduler; + private volatile IDisposable _disposable; + + /// + /// Initializes a new instance of the class that uses an on which to dispose the disposable. + /// + /// Scheduler where the disposable resource will be disposed on. + /// Disposable resource to dispose on the given scheduler. + /// or is null. + public ScheduledDisposable(IScheduler scheduler, IDisposable disposable) + { + if (scheduler == null) + throw new ArgumentNullException("scheduler"); + if (disposable == null) + throw new ArgumentNullException("disposable"); + + _scheduler = scheduler; + _disposable = disposable; + } + + /// + /// Gets the scheduler where the disposable resource will be disposed on. + /// + public IScheduler Scheduler + { + get { return _scheduler; } + } + + /// + /// Gets the underlying disposable. After disposal, the result is undefined. + /// + public IDisposable Disposable + { + get + { + var current = _disposable; + + if (current == BooleanDisposable.True) + return DefaultDisposable.Instance; // Don't leak the sentinel value. + + return current; + } + } + + /// + /// Gets a value that indicates whether the object is disposed. + /// + public bool IsDisposed + { + get { return _disposable == BooleanDisposable.True; } + } + + /// + /// Disposes the wrapped disposable on the provided scheduler. + /// + public void Dispose() + { + Scheduler.Schedule(DisposeInner); + } + + private void DisposeInner() + { +#pragma warning disable 0420 + var disposable = Interlocked.Exchange(ref _disposable, BooleanDisposable.True); +#pragma warning restore 0420 + + if (disposable != BooleanDisposable.True) + { + disposable.Dispose(); + } + } + } +} -- cgit v1.2.3