ContextDisposable.cs 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
  2. #if !NO_SYNCCTX
  3. using System.Reactive.Concurrency;
  4. using System.Threading;
  5. namespace System.Reactive.Disposables
  6. {
  7. /// <summary>
  8. /// Represents a disposable resource whose disposal invocation will be posted to the specified <seealso cref="T:System.Threading.SynchronizationContext"/>.
  9. /// </summary>
  10. public sealed class ContextDisposable : ICancelable
  11. {
  12. private readonly SynchronizationContext _context;
  13. private volatile IDisposable _disposable;
  14. /// <summary>
  15. /// Initializes a new instance of the <see cref="T:System.Reactive.Disposables.ContextDisposable"/> class that uses the specified <see cref="T:System.Threading.SynchronizationContext"/> on which to dispose the specified disposable resource.
  16. /// </summary>
  17. /// <param name="context">Context to perform disposal on.</param>
  18. /// <param name="disposable">Disposable whose Dispose operation to run on the given synchronization context.</param>
  19. /// <exception cref="ArgumentNullException"><paramref name="context"/> or <paramref name="disposable"/> is null.</exception>
  20. public ContextDisposable(SynchronizationContext context, IDisposable disposable)
  21. {
  22. if (context == null)
  23. throw new ArgumentNullException("context");
  24. if (disposable == null)
  25. throw new ArgumentNullException("disposable");
  26. _context = context;
  27. _disposable = disposable;
  28. }
  29. /// <summary>
  30. /// Gets the provided <see cref="T:System.Threading.SynchronizationContext"/>.
  31. /// </summary>
  32. public SynchronizationContext Context
  33. {
  34. get { return _context; }
  35. }
  36. /// <summary>
  37. /// Gets a value that indicates whether the object is disposed.
  38. /// </summary>
  39. public bool IsDisposed
  40. {
  41. get { return _disposable == BooleanDisposable.True; }
  42. }
  43. /// <summary>
  44. /// Disposes the underlying disposable on the provided <see cref="T:System.Threading.SynchronizationContext"/>.
  45. /// </summary>
  46. public void Dispose()
  47. {
  48. #pragma warning disable 0420
  49. var disposable = Interlocked.Exchange(ref _disposable, BooleanDisposable.True);
  50. #pragma warning restore 0420
  51. if (disposable != BooleanDisposable.True)
  52. {
  53. _context.PostWithStartComplete(d => d.Dispose(), disposable);
  54. }
  55. }
  56. }
  57. }
  58. #endif