Browse Source

Add TrySetFirst to MultiDisposableValue. More usages of MultiDisposableValue are now possible.

Daniel Weber 5 years ago
parent
commit
73a17c096a

+ 4 - 4
Rx.NET/Source/src/System.Reactive/Concurrency/EventLoopScheduler.cs

@@ -208,7 +208,7 @@ namespace System.Reactive.Concurrency
 
             private TState _state;
             private TimeSpan _next;
-            private IDisposable _task;
+            private MultipleAssignmentDisposableValue _task;
 
             public PeriodicallyScheduledWorkItem(EventLoopScheduler scheduler, TState state, TimeSpan period, Func<TState, TState> action)
             {
@@ -218,14 +218,14 @@ namespace System.Reactive.Concurrency
                 _scheduler = scheduler;
                 _next = scheduler._stopwatch.Elapsed + period;
 
-                Disposable.TrySetSingle(ref _task, scheduler.Schedule(this, _next - scheduler._stopwatch.Elapsed, static (_, s) => s.Tick(_)));
+                _task.TrySetFirst(scheduler.Schedule(this, _next - scheduler._stopwatch.Elapsed, static (_, s) => s.Tick(_)));
             }
 
             private IDisposable Tick(IScheduler self)
             {
                 _next += _period;
 
-                Disposable.TrySetMultiple(ref _task, self.Schedule(this, _next - _scheduler._stopwatch.Elapsed, static (_, s) => s.Tick(_)));
+                _task.Disposable = self.Schedule(this, _next - _scheduler._stopwatch.Elapsed, static (_, s) => s.Tick(_));
 
                 _gate.Wait(
                     this,
@@ -236,7 +236,7 @@ namespace System.Reactive.Concurrency
 
             public void Dispose()
             {
-                Disposable.Dispose(ref _task);
+                _task.Dispose();
                 _gate.Dispose();
             }
         }

+ 2 - 0
Rx.NET/Source/src/System.Reactive/Disposables/MultipleAssignmentDisposableValue.cs

@@ -32,6 +32,8 @@ namespace System.Reactive.Disposables
             set => Disposables.Disposable.TrySetMultiple(ref _current, value);
         }
 
+        public bool TrySetFirst(IDisposable disposable) => Disposables.Disposable.TrySetSingle(ref _current, disposable) == TrySetSingleResult.Success;
+
         /// <summary>
         /// Disposes the underlying disposable as well as all future replacements.
         /// </summary>

+ 4 - 4
Rx.NET/Source/src/System.Reactive/Linq/Observable/Range.cs

@@ -28,7 +28,7 @@ namespace System.Reactive.Linq.ObservableImpl
         {
             private readonly int _end;
             private int _index;
-            private IDisposable? _task;
+            private MultipleAssignmentDisposableValue _task;
 
             public RangeSink(int start, int count, IObserver<int> observer)
                 : base(observer)
@@ -40,7 +40,7 @@ namespace System.Reactive.Linq.ObservableImpl
             public void Run(IScheduler scheduler)
             {
                 var first = scheduler.Schedule(this, static (innerScheduler, @this) => @this.LoopRec(innerScheduler));
-                Disposable.TrySetSingle(ref _task, first);
+                _task.TrySetFirst(first);
             }
 
             protected override void Dispose(bool disposing)
@@ -48,7 +48,7 @@ namespace System.Reactive.Linq.ObservableImpl
                 base.Dispose(disposing);
                 if (disposing)
                 {
-                    Disposable.Dispose(ref _task);
+                    _task.Dispose();
                 }
             }
 
@@ -61,7 +61,7 @@ namespace System.Reactive.Linq.ObservableImpl
                     _index = idx + 1;
                     ForwardOnNext(idx);
                     var next = scheduler.Schedule(this, static (innerScheduler, @this) => @this.LoopRec(innerScheduler));
-                    Disposable.TrySetMultiple(ref _task, next);
+                    _task.Disposable = next;
                 }
                 else
                 {

+ 8 - 8
Rx.NET/Source/src/System.Reactive/Linq/Observable/Repeat.cs

@@ -28,7 +28,7 @@ namespace System.Reactive.Linq.ObservableImpl
             {
                 private readonly TResult _value;
 
-                private IDisposable? _task;
+                private MultipleAssignmentDisposableValue _task;
 
                 public _(TResult value, IObserver<TResult> observer)
                     : base(observer)
@@ -39,7 +39,7 @@ namespace System.Reactive.Linq.ObservableImpl
                 public void Run(IScheduler scheduler)
                 {
                     var first = scheduler.Schedule(this, static (innerScheduler, @this) => @this.LoopRecInf(innerScheduler));
-                    Disposable.TrySetSingle(ref _task, first);
+                    _task.TrySetFirst(first);
                 }
 
                 protected override void Dispose(bool disposing)
@@ -48,7 +48,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
                     if (disposing)
                     {
-                        Disposable.Dispose(ref _task);
+                        _task.Dispose();
                     }
                 }
 
@@ -57,7 +57,7 @@ namespace System.Reactive.Linq.ObservableImpl
                     ForwardOnNext(_value);
 
                     var next = scheduler.Schedule(this, static (innerScheduler, @this) => @this.LoopRecInf(innerScheduler));
-                    Disposable.TrySetMultiple(ref _task, next);
+                    _task.Disposable = next;
 
                     return Disposable.Empty;
                 }
@@ -130,7 +130,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
                 private int _remaining;
 
-                private IDisposable? _task;
+                private MultipleAssignmentDisposableValue _task;
 
                 public _(TResult value, int repeatCount, IObserver<TResult> observer)
                     : base(observer)
@@ -142,7 +142,7 @@ namespace System.Reactive.Linq.ObservableImpl
                 public void Run(IScheduler scheduler)
                 {
                     var first = scheduler.Schedule(this, static (innerScheduler, @this) => @this.LoopRec(innerScheduler));
-                    Disposable.TrySetSingle(ref _task, first);
+                    _task.TrySetFirst(first);
                 }
 
                 protected override void Dispose(bool disposing)
@@ -151,7 +151,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
                     if (disposing)
                     {
-                        Disposable.Dispose(ref _task);
+                        _task.Dispose();
                     }
                 }
 
@@ -171,7 +171,7 @@ namespace System.Reactive.Linq.ObservableImpl
                     else
                     {
                         var next = scheduler.Schedule(this, static (innerScheduler, @this) => @this.LoopRec(innerScheduler));
-                        Disposable.TrySetMultiple(ref _task, next);
+                        _task.Disposable = next;
                     }
 
                     return Disposable.Empty;

+ 10 - 10
Rx.NET/Source/src/System.Reactive/Linq/Observable/TakeLast.cs

@@ -41,13 +41,13 @@ namespace System.Reactive.Linq.ObservableImpl
                     _queue = new Queue<TSource>();
                 }
 
-                private IDisposable? _loopDisposable;
+                private MultipleAssignmentDisposableValue _loopDisposable;
 
                 protected override void Dispose(bool disposing)
                 {
                     if (disposing)
                     {
-                        Disposable.Dispose(ref _loopDisposable);
+                        _loopDisposable.Dispose();
                     }
 
                     base.Dispose(disposing);
@@ -70,12 +70,12 @@ namespace System.Reactive.Linq.ObservableImpl
                     var longRunning = _loopScheduler.AsLongRunning();
                     if (longRunning != null)
                     {
-                        Disposable.TrySetSingle(ref _loopDisposable, longRunning.ScheduleLongRunning(this, static (@this, c) => @this.Loop(c)));
+                        _loopDisposable.TrySetFirst(longRunning.ScheduleLongRunning(this, static (@this, c) => @this.Loop(c)));
                     }
                     else
                     {
                         var first = _loopScheduler.Schedule(this, static (innerScheduler, @this) => @this.LoopRec(innerScheduler));
-                        Disposable.TrySetSingle(ref _loopDisposable, first);
+                        _loopDisposable.TrySetFirst(first);
                     }
                 }
 
@@ -86,7 +86,7 @@ namespace System.Reactive.Linq.ObservableImpl
                         ForwardOnNext(_queue.Dequeue());
 
                         var next = scheduler.Schedule(this, static (innerScheduler, @this) => @this.LoopRec(innerScheduler));
-                        Disposable.TrySetMultiple(ref _loopDisposable, next);
+                        _loopDisposable.Disposable = next;
                     }
                     else
                     {
@@ -150,7 +150,7 @@ namespace System.Reactive.Linq.ObservableImpl
                     _queue = new Queue<Reactive.TimeInterval<TSource>>();
                 }
 
-                private IDisposable? _loopDisposable;
+                private MultipleAssignmentDisposableValue _loopDisposable;
                 private IStopwatch? _watch;
 
                 public void Run(IObservable<TSource> source, IScheduler scheduler)
@@ -163,7 +163,7 @@ namespace System.Reactive.Linq.ObservableImpl
                 {
                     if (disposing)
                     {
-                        Disposable.Dispose(ref _loopDisposable);
+                        _loopDisposable.Dispose();
                     }
 
                     base.Dispose(disposing);
@@ -186,12 +186,12 @@ namespace System.Reactive.Linq.ObservableImpl
                     var longRunning = _loopScheduler.AsLongRunning();
                     if (longRunning != null)
                     {
-                        Disposable.TrySetSingle(ref _loopDisposable, longRunning.ScheduleLongRunning(this, static (@this, c) => @this.Loop(c)));
+                        _loopDisposable.TrySetFirst(longRunning.ScheduleLongRunning(this, static (@this, c) => @this.Loop(c)));
                     }
                     else
                     {
                         var first = _loopScheduler.Schedule(this, static (innerScheduler, @this) => @this.LoopRec(innerScheduler));
-                        Disposable.TrySetSingle(ref _loopDisposable, first);
+                        _loopDisposable.TrySetFirst(first);
                     }
                 }
 
@@ -202,7 +202,7 @@ namespace System.Reactive.Linq.ObservableImpl
                         ForwardOnNext(_queue.Dequeue().Value);
 
                         var next = scheduler.Schedule(this, static (innerScheduler, @this) => @this.LoopRec(innerScheduler));
-                        Disposable.TrySetMultiple(ref _loopDisposable, next);
+                        _loopDisposable.Disposable = next;
                     }
                     else
                     {