ソースを参照

Strengthen the concept of the Sink class.

Before, it would wrap, yet still internally expose an observer. Inheriting classes would access it directly and the pattern of disposing the Sink after calling OnCompleted/OnError on the wrapped observer would be on them and repeat throughout the code. This commit encapsulates the observer and exposes Forward*-methods, taking care of disposing at the right places. The result is a lot of saved duplicated code. Moreover, we find that almost all classes inheriting from Sink also implement an IObserver of some kind by themselves, so we establish a base class Sink<TSource, TTarget>. The concept of a Sink is now more obvious, i.e. it serves as the logic between the source-stream and the emitted target stream. At last, we introduce IdentitySink which will just relay events, again, this will save a lot of duplicated code. (#493)
Daniel C. Weber 7 年 前
コミット
f2ea2121ea
96 ファイル変更1293 行追加2768 行削除
  1. 7 9
      Rx.NET/Source/src/System.Reactive/Concurrency/Synchronization.ObserveOn.cs
  2. 7 9
      Rx.NET/Source/src/System.Reactive/Concurrency/Synchronization.Synchronize.cs
  3. 18 0
      Rx.NET/Source/src/System.Reactive/Internal/IdentitySink.cs
  4. 5 5
      Rx.NET/Source/src/System.Reactive/Internal/Producer.cs
  5. 60 20
      Rx.NET/Source/src/System.Reactive/Internal/Sink.cs
  6. 5 13
      Rx.NET/Source/src/System.Reactive/Internal/TailRecursiveSink.cs
  7. 1 18
      Rx.NET/Source/src/System.Reactive/Linq/Observable/AddRef.cs
  8. 24 40
      Rx.NET/Source/src/System.Reactive/Linq/Observable/Aggregate.cs
  9. 9 18
      Rx.NET/Source/src/System.Reactive/Linq/Observable/All.cs
  10. 15 32
      Rx.NET/Source/src/System.Reactive/Linq/Observable/Any.cs
  11. 1 18
      Rx.NET/Source/src/System.Reactive/Linq/Observable/AsObservable.cs
  12. 70 155
      Rx.NET/Source/src/System.Reactive/Linq/Observable/Average.cs
  13. 50 63
      Rx.NET/Source/src/System.Reactive/Linq/Observable/Buffer.cs
  14. 2 20
      Rx.NET/Source/src/System.Reactive/Linq/Observable/Case.cs
  15. 4 17
      Rx.NET/Source/src/System.Reactive/Linq/Observable/Cast.cs
  16. 9 37
      Rx.NET/Source/src/System.Reactive/Linq/Observable/Catch.cs
  17. 25 40
      Rx.NET/Source/src/System.Reactive/Linq/Observable/CombineLatest.cs
  18. 0 11
      Rx.NET/Source/src/System.Reactive/Linq/Observable/Concat.cs
  19. 8 17
      Rx.NET/Source/src/System.Reactive/Linq/Observable/Contains.cs
  20. 12 28
      Rx.NET/Source/src/System.Reactive/Linq/Observable/Count.cs
  21. 7 13
      Rx.NET/Source/src/System.Reactive/Linq/Observable/DefaultIfEmpty.cs
  22. 2 20
      Rx.NET/Source/src/System.Reactive/Linq/Observable/Defer.cs
  23. 19 33
      Rx.NET/Source/src/System.Reactive/Linq/Observable/Delay.cs
  24. 1 18
      Rx.NET/Source/src/System.Reactive/Linq/Observable/DelaySubscription.cs
  25. 5 19
      Rx.NET/Source/src/System.Reactive/Linq/Observable/Dematerialize.cs
  26. 4 17
      Rx.NET/Source/src/System.Reactive/Linq/Observable/Distinct.cs
  27. 5 19
      Rx.NET/Source/src/System.Reactive/Linq/Observable/DistinctUntilChanged.cs
  28. 24 47
      Rx.NET/Source/src/System.Reactive/Linq/Observable/Do.cs
  29. 0 11
      Rx.NET/Source/src/System.Reactive/Linq/Observable/DoWhile.cs
  30. 6 14
      Rx.NET/Source/src/System.Reactive/Linq/Observable/ElementAt.cs
  31. 7 15
      Rx.NET/Source/src/System.Reactive/Linq/Observable/ElementAtOrDefault.cs
  32. 2 3
      Rx.NET/Source/src/System.Reactive/Linq/Observable/Empty.cs
  33. 1 18
      Rx.NET/Source/src/System.Reactive/Linq/Observable/Finally.cs
  34. 13 30
      Rx.NET/Source/src/System.Reactive/Linq/Observable/FirstAsync.cs
  35. 15 32
      Rx.NET/Source/src/System.Reactive/Linq/Observable/FirstOrDefaultAsync.cs
  36. 0 11
      Rx.NET/Source/src/System.Reactive/Linq/Observable/For.cs
  37. 15 24
      Rx.NET/Source/src/System.Reactive/Linq/Observable/Generate.cs
  38. 7 9
      Rx.NET/Source/src/System.Reactive/Linq/Observable/GroupBy.cs
  39. 11 14
      Rx.NET/Source/src/System.Reactive/Linq/Observable/GroupByUntil.cs
  40. 5 8
      Rx.NET/Source/src/System.Reactive/Linq/Observable/GroupJoin.cs
  41. 2 20
      Rx.NET/Source/src/System.Reactive/Linq/Observable/If.cs
  42. 2 14
      Rx.NET/Source/src/System.Reactive/Linq/Observable/IgnoreElements.cs
  43. 7 15
      Rx.NET/Source/src/System.Reactive/Linq/Observable/IsEmpty.cs
  44. 13 23
      Rx.NET/Source/src/System.Reactive/Linq/Observable/Join.cs
  45. 13 30
      Rx.NET/Source/src/System.Reactive/Linq/Observable/LastAsync.cs
  46. 11 26
      Rx.NET/Source/src/System.Reactive/Linq/Observable/LastOrDefaultAsync.cs
  47. 12 28
      Rx.NET/Source/src/System.Reactive/Linq/Observable/LongCount.cs
  48. 9 11
      Rx.NET/Source/src/System.Reactive/Linq/Observable/Materialize.cs
  49. 64 155
      Rx.NET/Source/src/System.Reactive/Linq/Observable/Max.cs
  50. 7 16
      Rx.NET/Source/src/System.Reactive/Linq/Observable/MaxBy.cs
  51. 27 39
      Rx.NET/Source/src/System.Reactive/Linq/Observable/Merge.cs
  52. 64 155
      Rx.NET/Source/src/System.Reactive/Linq/Observable/Min.cs
  53. 7 16
      Rx.NET/Source/src/System.Reactive/Linq/Observable/MinBy.cs
  54. 2 20
      Rx.NET/Source/src/System.Reactive/Linq/Observable/Multicast.cs
  55. 3 15
      Rx.NET/Source/src/System.Reactive/Linq/Observable/OfType.cs
  56. 0 5
      Rx.NET/Source/src/System.Reactive/Linq/Observable/OnErrorResumeNext.cs
  57. 5 8
      Rx.NET/Source/src/System.Reactive/Linq/Observable/Range.cs
  58. 1 18
      Rx.NET/Source/src/System.Reactive/Linq/Observable/RefCount.cs
  59. 8 11
      Rx.NET/Source/src/System.Reactive/Linq/Observable/Repeat.cs
  60. 3 4
      Rx.NET/Source/src/System.Reactive/Linq/Observable/Return.cs
  61. 18 27
      Rx.NET/Source/src/System.Reactive/Linq/Observable/Sample.cs
  62. 8 34
      Rx.NET/Source/src/System.Reactive/Linq/Observable/Scan.cs
  63. 8 34
      Rx.NET/Source/src/System.Reactive/Linq/Observable/Select.cs
  64. 106 210
      Rx.NET/Source/src/System.Reactive/Linq/Observable/SelectMany.cs
  65. 31 54
      Rx.NET/Source/src/System.Reactive/Linq/Observable/SequenceEqual.cs
  66. 15 34
      Rx.NET/Source/src/System.Reactive/Linq/Observable/SingleAsync.cs
  67. 13 30
      Rx.NET/Source/src/System.Reactive/Linq/Observable/SingleOrDefaultAsync.cs
  68. 6 30
      Rx.NET/Source/src/System.Reactive/Linq/Observable/Skip.cs
  69. 9 28
      Rx.NET/Source/src/System.Reactive/Linq/Observable/SkipLast.cs
  70. 13 25
      Rx.NET/Source/src/System.Reactive/Linq/Observable/SkipUntil.cs
  71. 10 36
      Rx.NET/Source/src/System.Reactive/Linq/Observable/SkipWhile.cs
  72. 55 129
      Rx.NET/Source/src/System.Reactive/Linq/Observable/Sum.cs
  73. 9 14
      Rx.NET/Source/src/System.Reactive/Linq/Observable/Switch.cs
  74. 7 9
      Rx.NET/Source/src/System.Reactive/Linq/Observable/Synchronize.cs
  75. 12 28
      Rx.NET/Source/src/System.Reactive/Linq/Observable/Take.cs
  76. 14 28
      Rx.NET/Source/src/System.Reactive/Linq/Observable/TakeLast.cs
  77. 10 24
      Rx.NET/Source/src/System.Reactive/Linq/Observable/TakeLastBuffer.cs
  78. 15 22
      Rx.NET/Source/src/System.Reactive/Linq/Observable/TakeUntil.cs
  79. 10 38
      Rx.NET/Source/src/System.Reactive/Linq/Observable/TakeWhile.cs
  80. 20 26
      Rx.NET/Source/src/System.Reactive/Linq/Observable/Throttle.cs
  81. 2 3
      Rx.NET/Source/src/System.Reactive/Linq/Observable/Throw.cs
  82. 3 15
      Rx.NET/Source/src/System.Reactive/Linq/Observable/TimeInterval.cs
  83. 23 31
      Rx.NET/Source/src/System.Reactive/Linq/Observable/Timeout.cs
  84. 8 9
      Rx.NET/Source/src/System.Reactive/Linq/Observable/Timer.cs
  85. 3 15
      Rx.NET/Source/src/System.Reactive/Linq/Observable/Timestamp.cs
  86. 5 12
      Rx.NET/Source/src/System.Reactive/Linq/Observable/ToArray.cs
  87. 6 14
      Rx.NET/Source/src/System.Reactive/Linq/Observable/ToDictionary.cs
  88. 5 12
      Rx.NET/Source/src/System.Reactive/Linq/Observable/ToList.cs
  89. 6 14
      Rx.NET/Source/src/System.Reactive/Linq/Observable/ToLookup.cs
  90. 8 11
      Rx.NET/Source/src/System.Reactive/Linq/Observable/ToObservable.cs
  91. 1 18
      Rx.NET/Source/src/System.Reactive/Linq/Observable/Using.cs
  92. 8 35
      Rx.NET/Source/src/System.Reactive/Linq/Observable/Where.cs
  93. 0 11
      Rx.NET/Source/src/System.Reactive/Linq/Observable/While.cs
  94. 48 61
      Rx.NET/Source/src/System.Reactive/Linq/Observable/Window.cs
  95. 6 10
      Rx.NET/Source/src/System.Reactive/Linq/Observable/WithLatestFrom.cs
  96. 31 63
      Rx.NET/Source/src/System.Reactive/Linq/Observable/Zip.cs

+ 7 - 9
Rx.NET/Source/src/System.Reactive/Concurrency/Synchronization.ObserveOn.cs

@@ -62,7 +62,7 @@ namespace System.Reactive.Concurrency
             [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1062:Validate arguments of public methods", MessageId = "2", Justification = "Visibility restricted to friend assemblies. Those should be correct by inspection.")]
             protected override IDisposable Run(_ sink) => sink.Run(_source);
 
-            internal sealed class _ : Sink<TSource>, IObserver<TSource>
+            internal sealed class _ : IdentitySink<TSource>
             {
                 private readonly SynchronizationContext _context;
 
@@ -89,36 +89,34 @@ namespace System.Reactive.Concurrency
                     return StableCompositeDisposable.Create(d, c);
                 }
 
-                public void OnNext(TSource value)
+                public override void OnNext(TSource value)
                 {
                     _context.Post(OnNextPosted, value);
                 }
 
-                public void OnError(Exception error)
+                public override void OnError(Exception error)
                 {
                     _context.Post(OnErrorPosted, error);
                 }
 
-                public void OnCompleted()
+                public override void OnCompleted()
                 {
                     _context.Post(OnCompletedPosted, state: null);
                 }
 
                 private void OnNextPosted(object value)
                 {
-                    _observer.OnNext((TSource)value);
+                    ForwardOnNext((TSource)value);
                 }
 
                 private void OnErrorPosted(object error)
                 {
-                    _observer.OnError((Exception)error);
-                    Dispose();
+                    ForwardOnError((Exception)error);
                 }
 
                 private void OnCompletedPosted(object ignored)
                 {
-                    _observer.OnCompleted();
-                    Dispose();
+                    ForwardOnCompleted();
                 }
             }
         }

+ 7 - 9
Rx.NET/Source/src/System.Reactive/Concurrency/Synchronization.Synchronize.cs

@@ -25,7 +25,7 @@ namespace System.Reactive.Concurrency
         [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1062:Validate arguments of public methods", MessageId = "2", Justification = "Visibility restricted to friend assemblies. Those should be correct by inspection.")]
         protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-        internal sealed class _ : Sink<TSource>, IObserver<TSource>
+        internal sealed class _ : IdentitySink<TSource>
         {
             private readonly Synchronize<TSource> _parent;
             private readonly object _gate;
@@ -37,29 +37,27 @@ namespace System.Reactive.Concurrency
                 _gate = _parent._gate ?? new object();
             }
 
-            public void OnNext(TSource value)
+            public override void OnNext(TSource value)
             {
                 lock (_gate)
                 {
-                    _observer.OnNext(value);
+                    ForwardOnNext(value);
                 }
             }
 
-            public void OnError(Exception error)
+            public override void OnError(Exception error)
             {
                 lock (_gate)
                 {
-                    _observer.OnError(error);
-                    Dispose();
+                    ForwardOnError(error);
                 }
             }
 
-            public void OnCompleted()
+            public override void OnCompleted()
             {
                 lock (_gate)
                 {
-                    _observer.OnCompleted();
-                    Dispose();
+                    ForwardOnCompleted();
                 }
             }
         }

+ 18 - 0
Rx.NET/Source/src/System.Reactive/Internal/IdentitySink.cs

@@ -0,0 +1,18 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the Apache 2.0 License.
+// See the LICENSE file in the project root for more information. 
+
+namespace System.Reactive
+{
+    internal abstract class IdentitySink<T> : Sink<T, T>
+    {
+        protected IdentitySink(IObserver<T> observer, IDisposable cancel) : base(observer, cancel)
+        {
+        }
+
+        public override void OnNext(T value)
+        {
+            ForwardOnNext(value);
+        }
+    }
+}

+ 5 - 5
Rx.NET/Source/src/System.Reactive/Internal/Producer.cs

@@ -83,7 +83,7 @@ namespace System.Reactive
         protected abstract IDisposable Run(IObserver<TSource> observer);
     }
 
-    internal abstract class Producer<TSource, TSink> : IProducer<TSource>
+    internal abstract class Producer<TTarget, TSink> : IProducer<TTarget>
         where TSink : IDisposable
     {
         /// <summary>
@@ -91,7 +91,7 @@ namespace System.Reactive
         /// </summary>
         /// <param name="observer">Observer to send notifications on. The implementation of a producer must ensure the correct message grammar on the observer.</param>
         /// <returns>IDisposable to cancel the subscription. This causes the underlying sink to be notified of unsubscription, causing it to prevent further messages from being sent to the observer.</returns>
-        public IDisposable Subscribe(IObserver<TSource> observer)
+        public IDisposable Subscribe(IObserver<TTarget> observer)
         {
             if (observer == null)
                 throw new ArgumentNullException(nameof(observer));
@@ -99,7 +99,7 @@ namespace System.Reactive
             return SubscribeRaw(observer, enableSafeguard: true);
         }
 
-        public IDisposable SubscribeRaw(IObserver<TSource> observer, bool enableSafeguard)
+        public IDisposable SubscribeRaw(IObserver<TTarget> observer, bool enableSafeguard)
         {
             var subscription = new SubscriptionDisposable();
 
@@ -109,7 +109,7 @@ namespace System.Reactive
             //
             if (enableSafeguard)
             {
-                observer = SafeObserver<TSource>.Create(observer, subscription);
+                observer = SafeObserver<TTarget>.Create(observer, subscription);
             }
 
             var sink = CreateSink(observer, subscription.Inner);
@@ -148,7 +148,7 @@ namespace System.Reactive
         /// <param name="sink">The sink object.</param>
         protected abstract IDisposable Run(TSink sink);
 
-        protected abstract TSink CreateSink(IObserver<TSource> observer, IDisposable cancel);
+        protected abstract TSink CreateSink(IObserver<TTarget> observer, IDisposable cancel);
     }
 
     internal sealed class SubscriptionDisposable : ICancelable

+ 60 - 20
Rx.NET/Source/src/System.Reactive/Internal/Sink.cs

@@ -6,55 +6,95 @@ using System.Threading;
 
 namespace System.Reactive
 {
-    /// <summary>
-    /// Base class for implementation of query operators, providing a lightweight sink that can be disposed to mute the outgoing observer.
-    /// </summary>
-    /// <typeparam name="TSource">Type of the resulting sequence's elements.</typeparam>
-    /// <remarks>Implementations of sinks are responsible to enforce the message grammar on the associated observer. Upon sending a terminal message, a pairing Dispose call should be made to trigger cancellation of related resources and to mute the outgoing observer.</remarks>
-    internal abstract class Sink<TSource> : IDisposable
+    internal abstract class Sink<TTarget> : IDisposable
     {
-        protected internal volatile IObserver<TSource> _observer;
         private IDisposable _cancel;
+        private volatile IObserver<TTarget> _observer;
 
-        public Sink(IObserver<TSource> observer, IDisposable cancel)
+        protected Sink(IObserver<TTarget> observer, IDisposable cancel)
         {
             _observer = observer;
             _cancel = cancel;
         }
 
-        public virtual void Dispose()
+        public void Dispose()
         {
-            _observer = NopObserver<TSource>.Instance;
+            Dispose(true);
+        }
+
+        protected virtual void Dispose(bool disposing)
+        {
+            _observer = NopObserver<TTarget>.Instance;
 
             Interlocked.Exchange(ref _cancel, null)?.Dispose();
         }
 
-        public IObserver<TSource> GetForwarder() => new _(this);
+        protected void ForwardOnNext(TTarget value)
+        {
+            _observer.OnNext(value);
+        }
+
+        protected void ForwardOnCompleted()
+        {
+            _observer.OnCompleted();
+            Dispose();
+        }
+
+        protected void ForwardOnError(Exception error)
+        {
+            _observer.OnError(error);
+            Dispose();
+        }
+    }
+
+    /// <summary>
+    /// Base class for implementation of query operators, providing a lightweight sink that can be disposed to mute the outgoing observer.
+    /// </summary>
+    /// <typeparam name="TTarget">Type of the resulting sequence's elements.</typeparam>
+    /// <typeparam name="TSource"></typeparam>
+    /// <remarks>Implementations of sinks are responsible to enforce the message grammar on the associated observer. Upon sending a terminal message, a pairing Dispose call should be made to trigger cancellation of related resources and to mute the outgoing observer.</remarks>
+    internal abstract class Sink<TSource, TTarget> : Sink<TTarget>, IObserver<TSource>
+    {
+        protected Sink(IObserver<TTarget> observer, IDisposable cancel) : base(observer, cancel)
+        {
+        }
+
+        public abstract void OnNext(TSource value);
+
+        public virtual void OnError(Exception error)
+        {
+            ForwardOnError(error);
+        }
+
+        public virtual void OnCompleted()
+        {
+            ForwardOnCompleted();
+        }
+
+        public IObserver<TTarget> GetForwarder() => new _(this);
 
-        private sealed class _ : IObserver<TSource>
+        private sealed class _ : IObserver<TTarget>
         {
-            private readonly Sink<TSource> _forward;
+            private readonly Sink<TSource, TTarget> _forward;
 
-            public _(Sink<TSource> forward)
+            public _(Sink<TSource, TTarget> forward)
             {
                 _forward = forward;
             }
 
-            public void OnNext(TSource value)
+            public void OnNext(TTarget value)
             {
-                _forward._observer.OnNext(value);
+                _forward.ForwardOnNext(value);
             }
 
             public void OnError(Exception error)
             {
-                _forward._observer.OnError(error);
-                _forward.Dispose();
+                _forward.ForwardOnError(error);
             }
 
             public void OnCompleted()
             {
-                _forward._observer.OnCompleted();
-                _forward.Dispose();
+                _forward.ForwardOnCompleted();
             }
         }
     }

+ 5 - 13
Rx.NET/Source/src/System.Reactive/Internal/TailRecursiveSink.cs

@@ -9,7 +9,7 @@ using System.Threading;
 
 namespace System.Reactive
 {
-    internal abstract class TailRecursiveSink<TSource> : Sink<TSource>, IObserver<TSource>
+    internal abstract class TailRecursiveSink<TSource> : IdentitySink<TSource>
     {
         public TailRecursiveSink(IObserver<TSource> observer, IDisposable cancel)
             : base(observer, cancel)
@@ -92,8 +92,7 @@ namespace System.Reactive
                         catch (Exception ex)
                         {
                             currentEnumerator.Dispose();
-                            _observer.OnError(ex);
-                            base.Dispose();
+                            ForwardOnError(ex);
                             Volatile.Write(ref _isDisposed, true);
                             continue;
                         }
@@ -195,28 +194,21 @@ namespace System.Reactive
             }
             catch (Exception exception)
             {
-                _observer.OnError(exception);
-                base.Dispose();
+                ForwardOnError(exception);
 
                 result = null;
                 return false;
             }
         }
 
-        public abstract void OnCompleted();
-        public abstract void OnError(Exception error);
-        public abstract void OnNext(TSource value);
-
         protected virtual void Done()
         {
-            _observer.OnCompleted();
-            base.Dispose();
+            ForwardOnCompleted();
         }
 
         protected virtual bool Fail(Exception error)
         {
-            _observer.OnError(error);
-            base.Dispose();
+            ForwardOnError(error);
 
             return false;
         }

+ 1 - 18
Rx.NET/Source/src/System.Reactive/Linq/Observable/AddRef.cs

@@ -21,29 +21,12 @@ namespace System.Reactive.Linq.ObservableImpl
 
         protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-        internal sealed class _ : Sink<TSource>, IObserver<TSource>
+        internal sealed class _ : IdentitySink<TSource>
         {
             public _(IObserver<TSource> observer, IDisposable cancel)
                 : base(observer, cancel)
             {
             }
-
-            public void OnNext(TSource value)
-            {
-                base._observer.OnNext(value);
-            }
-
-            public void OnError(Exception error)
-            {
-                base._observer.OnError(error);
-                base.Dispose();
-            }
-
-            public void OnCompleted()
-            {
-                base._observer.OnCompleted();
-                base.Dispose();
-            }
         }
     }
 }

+ 24 - 40
Rx.NET/Source/src/System.Reactive/Linq/Observable/Aggregate.cs

@@ -19,7 +19,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
         protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-        internal sealed class _ : Sink<TSource>, IObserver<TSource>
+        internal sealed class _ : IdentitySink<TSource>
         {
             private readonly Func<TSource, TSource, TSource> _accumulator;
             private TSource _accumulation;
@@ -33,7 +33,7 @@ namespace System.Reactive.Linq.ObservableImpl
                 _hasAccumulation = false;
             }
 
-            public void OnNext(TSource value)
+            public override void OnNext(TSource value)
             {
                 if (!_hasAccumulation)
                 {
@@ -48,30 +48,21 @@ namespace System.Reactive.Linq.ObservableImpl
                     }
                     catch (Exception exception)
                     {
-                        base._observer.OnError(exception);
-                        base.Dispose();
+                        ForwardOnError(exception);
                     }
                 }
             }
 
-            public void OnError(Exception error)
-            {
-                base._observer.OnError(error);
-                base.Dispose();
-            }
-
-            public void OnCompleted()
+            public override void OnCompleted()
             {
                 if (!_hasAccumulation)
                 {
-                    base._observer.OnError(new InvalidOperationException(Strings_Linq.NO_ELEMENTS));
-                    base.Dispose();
+                    ForwardOnError(new InvalidOperationException(Strings_Linq.NO_ELEMENTS));
                 }
                 else
                 {
-                    base._observer.OnNext(_accumulation);
-                    base._observer.OnCompleted();
-                    base.Dispose();
+                    ForwardOnNext(_accumulation);
+                    ForwardOnCompleted();
                 }
             }
         }
@@ -94,7 +85,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
         protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-        internal sealed class _ : Sink<TAccumulate>, IObserver<TSource>
+        internal sealed class _ : Sink<TSource, TAccumulate> 
         {
             private readonly Func<TAccumulate, TSource, TAccumulate> _accumulator;
             private TAccumulate _accumulation;
@@ -106,7 +97,7 @@ namespace System.Reactive.Linq.ObservableImpl
                 _accumulation = seed;
             }
 
-            public void OnNext(TSource value)
+            public override void OnNext(TSource value)
             {
                 try
                 {
@@ -114,22 +105,19 @@ namespace System.Reactive.Linq.ObservableImpl
                 }
                 catch (Exception exception)
                 {
-                    base._observer.OnError(exception);
-                    base.Dispose();
+                    ForwardOnError(exception);
                 }
             }
 
-            public void OnError(Exception error)
+            public override void OnError(Exception error)
             {
-                base._observer.OnError(error);
-                base.Dispose();
+                ForwardOnError(error);
             }
 
-            public void OnCompleted()
+            public override void OnCompleted()
             {
-                base._observer.OnNext(_accumulation);
-                base._observer.OnCompleted();
-                base.Dispose();
+                ForwardOnNext(_accumulation);
+                ForwardOnCompleted();
             }
         }
     }
@@ -153,7 +141,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
         protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-        internal sealed class _ : Sink<TResult>, IObserver<TSource>
+        internal sealed class _ : Sink<TSource, TResult> 
         {
             private readonly Func<TAccumulate, TSource, TAccumulate> _accumulator;
             private readonly Func<TAccumulate, TResult> _resultSelector;
@@ -169,7 +157,7 @@ namespace System.Reactive.Linq.ObservableImpl
                 _accumulation = parent._seed;
             }
 
-            public void OnNext(TSource value)
+            public override void OnNext(TSource value)
             {
                 try
                 {
@@ -177,18 +165,16 @@ namespace System.Reactive.Linq.ObservableImpl
                 }
                 catch (Exception exception)
                 {
-                    base._observer.OnError(exception);
-                    base.Dispose();
+                    ForwardOnError(exception);
                 }
             }
 
-            public void OnError(Exception error)
+            public override void OnError(Exception error)
             {
-                base._observer.OnError(error);
-                base.Dispose();
+                ForwardOnError(error);
             }
 
-            public void OnCompleted()
+            public override void OnCompleted()
             {
                 var result = default(TResult);
                 try
@@ -197,14 +183,12 @@ namespace System.Reactive.Linq.ObservableImpl
                 }
                 catch (Exception exception)
                 {
-                    base._observer.OnError(exception);
-                    base.Dispose();
+                    ForwardOnError(exception);
                     return;
                 }
 
-                base._observer.OnNext(result);
-                base._observer.OnCompleted();
-                base.Dispose();
+                ForwardOnNext(result);
+                ForwardOnCompleted();
             }
         }
     }

+ 9 - 18
Rx.NET/Source/src/System.Reactive/Linq/Observable/All.cs

@@ -19,7 +19,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
         protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-        internal sealed class _ : Sink<bool>, IObserver<TSource>
+        internal sealed class _ : Sink<TSource, bool> 
         {
             private readonly Func<TSource, bool> _predicate;
 
@@ -29,7 +29,7 @@ namespace System.Reactive.Linq.ObservableImpl
                 _predicate = predicate;
             }
 
-            public void OnNext(TSource value)
+            public override void OnNext(TSource value)
             {
                 var res = false;
                 try
@@ -38,30 +38,21 @@ namespace System.Reactive.Linq.ObservableImpl
                 }
                 catch (Exception ex)
                 {
-                    base._observer.OnError(ex);
-                    base.Dispose();
+                    ForwardOnError(ex);
                     return;
                 }
 
                 if (!res)
                 {
-                    base._observer.OnNext(false);
-                    base._observer.OnCompleted();
-                    base.Dispose();
+                    ForwardOnNext(false);
+                    ForwardOnCompleted();
                 }
             }
-
-            public void OnError(Exception error)
-            {
-                base._observer.OnError(error);
-                base.Dispose();
-            }
-
-            public void OnCompleted()
+            
+            public override void OnCompleted()
             {
-                base._observer.OnNext(true);
-                base._observer.OnCompleted();
-                base.Dispose();
+                ForwardOnNext(true);
+                ForwardOnCompleted();
             }
         }
     }

+ 15 - 32
Rx.NET/Source/src/System.Reactive/Linq/Observable/Any.cs

@@ -19,31 +19,23 @@ namespace System.Reactive.Linq.ObservableImpl
 
             protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-            internal sealed class _ : Sink<bool>, IObserver<TSource>
+            internal sealed class _ : Sink<TSource, bool> 
             {
                 public _(IObserver<bool> observer, IDisposable cancel)
                     : base(observer, cancel)
                 {
                 }
 
-                public void OnNext(TSource value)
+                public override void OnNext(TSource value)
                 {
-                    base._observer.OnNext(true);
-                    base._observer.OnCompleted();
-                    base.Dispose();
+                    ForwardOnNext(true);
+                    ForwardOnCompleted();
                 }
 
-                public void OnError(Exception error)
+                public override void OnCompleted()
                 {
-                    base._observer.OnError(error);
-                    base.Dispose();
-                }
-
-                public void OnCompleted()
-                {
-                    base._observer.OnNext(false);
-                    base._observer.OnCompleted();
-                    base.Dispose();
+                    ForwardOnNext(false);
+                    ForwardOnCompleted();
                 }
             }
         }
@@ -63,7 +55,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
             protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-            internal sealed class _ : Sink<bool>, IObserver<TSource>
+            internal sealed class _ : Sink<TSource, bool> 
             {
                 private readonly Func<TSource, bool> _predicate;
 
@@ -73,7 +65,7 @@ namespace System.Reactive.Linq.ObservableImpl
                     _predicate = predicate;
                 }
 
-                public void OnNext(TSource value)
+                public override void OnNext(TSource value)
                 {
                     var res = false;
                     try
@@ -82,30 +74,21 @@ namespace System.Reactive.Linq.ObservableImpl
                     }
                     catch (Exception ex)
                     {
-                        base._observer.OnError(ex);
-                        base.Dispose();
+                        ForwardOnError(ex);
                         return;
                     }
 
                     if (res)
                     {
-                        base._observer.OnNext(true);
-                        base._observer.OnCompleted();
-                        base.Dispose();
+                        ForwardOnNext(true);
+                        ForwardOnCompleted();
                     }
                 }
 
-                public void OnError(Exception error)
-                {
-                    base._observer.OnError(error);
-                    base.Dispose();
-                }
-
-                public void OnCompleted()
+                public override void OnCompleted()
                 {
-                    base._observer.OnNext(false);
-                    base._observer.OnCompleted();
-                    base.Dispose();
+                    ForwardOnNext(false);
+                    ForwardOnCompleted();
                 }
             }
         }

+ 1 - 18
Rx.NET/Source/src/System.Reactive/Linq/Observable/AsObservable.cs

@@ -19,29 +19,12 @@ namespace System.Reactive.Linq.ObservableImpl
 
         protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-        internal sealed class _ : Sink<TSource>, IObserver<TSource>
+        internal sealed class _ : IdentitySink<TSource>
         {
             public _(IObserver<TSource> observer, IDisposable cancel)
                 : base(observer, cancel)
             {
             }
-
-            public void OnNext(TSource value)
-            {
-                base._observer.OnNext(value);
-            }
-
-            public void OnError(Exception error)
-            {
-                base._observer.OnError(error);
-                base.Dispose();
-            }
-
-            public void OnCompleted()
-            {
-                base._observer.OnCompleted();
-                base.Dispose();
-            }
         }
     }
 }

+ 70 - 155
Rx.NET/Source/src/System.Reactive/Linq/Observable/Average.cs

@@ -17,7 +17,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
         protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-        internal sealed class _ : Sink<double>, IObserver<double>
+        internal sealed class _ : IdentitySink<double>
         {
             private double _sum;
             private long _count;
@@ -29,7 +29,7 @@ namespace System.Reactive.Linq.ObservableImpl
                 _count = 0L;
             }
 
-            public void OnNext(double value)
+            public override void OnNext(double value)
             {
                 try
                 {
@@ -41,30 +41,21 @@ namespace System.Reactive.Linq.ObservableImpl
                 }
                 catch (Exception ex)
                 {
-                    base._observer.OnError(ex);
-                    base.Dispose();
+                    ForwardOnError(ex);
                 }
             }
 
-            public void OnError(Exception error)
-            {
-                base._observer.OnError(error);
-                base.Dispose();
-            }
-
-            public void OnCompleted()
+            public override void OnCompleted()
             {
                 if (_count > 0)
                 {
-                    base._observer.OnNext(_sum / _count);
-                    base._observer.OnCompleted();
+                    ForwardOnNext(_sum / _count);
+                    ForwardOnCompleted();
                 }
                 else
                 {
-                    base._observer.OnError(new InvalidOperationException(Strings_Linq.NO_ELEMENTS));
+                    ForwardOnError(new InvalidOperationException(Strings_Linq.NO_ELEMENTS));
                 }
-
-                base.Dispose();
             }
         }
     }
@@ -82,7 +73,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
         protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-        internal sealed class _ : Sink<float>, IObserver<float>
+        internal sealed class _ : IdentitySink<float>
         {
             private double _sum; // NOTE: Uses a different accumulator type (double), conform LINQ to Objects.
             private long _count;
@@ -94,7 +85,7 @@ namespace System.Reactive.Linq.ObservableImpl
                 _count = 0L;
             }
 
-            public void OnNext(float value)
+            public override void OnNext(float value)
             {
                 try
                 {
@@ -106,30 +97,21 @@ namespace System.Reactive.Linq.ObservableImpl
                 }
                 catch (Exception ex)
                 {
-                    base._observer.OnError(ex);
-                    base.Dispose();
+                    ForwardOnError(ex);
                 }
             }
 
-            public void OnError(Exception error)
-            {
-                base._observer.OnError(error);
-                base.Dispose();
-            }
-
-            public void OnCompleted()
+            public override void OnCompleted()
             {
                 if (_count > 0)
                 {
-                    base._observer.OnNext((float)(_sum / _count));
-                    base._observer.OnCompleted();
+                    ForwardOnNext((float)(_sum / _count));
+                    ForwardOnCompleted();
                 }
                 else
                 {
-                    base._observer.OnError(new InvalidOperationException(Strings_Linq.NO_ELEMENTS));
+                    ForwardOnError(new InvalidOperationException(Strings_Linq.NO_ELEMENTS));
                 }
-
-                base.Dispose();
             }
         }
     }
@@ -147,7 +129,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
         protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-        internal sealed class _ : Sink<decimal>, IObserver<decimal>
+        internal sealed class _ : IdentitySink<decimal>
         {
             private decimal _sum;
             private long _count;
@@ -159,7 +141,7 @@ namespace System.Reactive.Linq.ObservableImpl
                 _count = 0L;
             }
 
-            public void OnNext(decimal value)
+            public override void OnNext(decimal value)
             {
                 try
                 {
@@ -171,30 +153,21 @@ namespace System.Reactive.Linq.ObservableImpl
                 }
                 catch (Exception ex)
                 {
-                    base._observer.OnError(ex);
-                    base.Dispose();
+                    ForwardOnError(ex);
                 }
             }
 
-            public void OnError(Exception error)
-            {
-                base._observer.OnError(error);
-                base.Dispose();
-            }
-
-            public void OnCompleted()
+            public override void OnCompleted()
             {
                 if (_count > 0)
                 {
-                    base._observer.OnNext(_sum / _count);
-                    base._observer.OnCompleted();
+                    ForwardOnNext(_sum / _count);
+                    ForwardOnCompleted();
                 }
                 else
                 {
-                    base._observer.OnError(new InvalidOperationException(Strings_Linq.NO_ELEMENTS));
+                    ForwardOnError(new InvalidOperationException(Strings_Linq.NO_ELEMENTS));
                 }
-
-                base.Dispose();
             }
         }
     }
@@ -212,7 +185,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
         protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-        internal sealed class _ : Sink<double>, IObserver<int>
+        internal sealed class _ : Sink<int, double> 
         {
             private long _sum;
             private long _count;
@@ -224,7 +197,7 @@ namespace System.Reactive.Linq.ObservableImpl
                 _count = 0L;
             }
 
-            public void OnNext(int value)
+            public override void OnNext(int value)
             {
                 try
                 {
@@ -236,30 +209,21 @@ namespace System.Reactive.Linq.ObservableImpl
                 }
                 catch (Exception ex)
                 {
-                    base._observer.OnError(ex);
-                    base.Dispose();
+                    ForwardOnError(ex);
                 }
             }
 
-            public void OnError(Exception error)
-            {
-                base._observer.OnError(error);
-                base.Dispose();
-            }
-
-            public void OnCompleted()
+            public override void OnCompleted()
             {
                 if (_count > 0)
                 {
-                    base._observer.OnNext((double)_sum / _count);
-                    base._observer.OnCompleted();
+                    ForwardOnNext((double)_sum / _count);
+                    ForwardOnCompleted();
                 }
                 else
                 {
-                    base._observer.OnError(new InvalidOperationException(Strings_Linq.NO_ELEMENTS));
+                    ForwardOnError(new InvalidOperationException(Strings_Linq.NO_ELEMENTS));
                 }
-
-                base.Dispose();
             }
         }
     }
@@ -277,7 +241,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
         protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-        internal sealed class _ : Sink<double>, IObserver<long>
+        internal sealed class _ : Sink<long, double> 
         {
             private long _sum;
             private long _count;
@@ -289,7 +253,7 @@ namespace System.Reactive.Linq.ObservableImpl
                 _count = 0L;
             }
 
-            public void OnNext(long value)
+            public override void OnNext(long value)
             {
                 try
                 {
@@ -301,30 +265,21 @@ namespace System.Reactive.Linq.ObservableImpl
                 }
                 catch (Exception ex)
                 {
-                    base._observer.OnError(ex);
-                    base.Dispose();
+                    ForwardOnError(ex);
                 }
             }
 
-            public void OnError(Exception error)
-            {
-                base._observer.OnError(error);
-                base.Dispose();
-            }
-
-            public void OnCompleted()
+            public override void OnCompleted()
             {
                 if (_count > 0)
                 {
-                    base._observer.OnNext((double)_sum / _count);
-                    base._observer.OnCompleted();
+                    ForwardOnNext((double)_sum / _count);
+                    ForwardOnCompleted();
                 }
                 else
                 {
-                    base._observer.OnError(new InvalidOperationException(Strings_Linq.NO_ELEMENTS));
+                    ForwardOnError(new InvalidOperationException(Strings_Linq.NO_ELEMENTS));
                 }
-
-                base.Dispose();
             }
         }
     }
@@ -342,7 +297,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
         protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-        internal sealed class _ : Sink<double?>, IObserver<double?>
+        internal sealed class _ : IdentitySink<double?>
         {
             private double _sum;
             private long _count;
@@ -354,7 +309,7 @@ namespace System.Reactive.Linq.ObservableImpl
                 _count = 0L;
             }
 
-            public void OnNext(double? value)
+            public override void OnNext(double? value)
             {
                 try
                 {
@@ -369,30 +324,22 @@ namespace System.Reactive.Linq.ObservableImpl
                 }
                 catch (Exception ex)
                 {
-                    base._observer.OnError(ex);
-                    base.Dispose();
+                    ForwardOnError(ex);
                 }
             }
 
-            public void OnError(Exception error)
-            {
-                base._observer.OnError(error);
-                base.Dispose();
-            }
-
-            public void OnCompleted()
+            public override void OnCompleted()
             {
                 if (_count > 0)
                 {
-                    base._observer.OnNext(_sum / _count);
+                    ForwardOnNext(_sum / _count);
                 }
                 else
                 {
-                    base._observer.OnNext(null);
+                    ForwardOnNext(null);
                 }
 
-                base._observer.OnCompleted();
-                base.Dispose();
+                ForwardOnCompleted();
             }
         }
     }
@@ -410,7 +357,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
         protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-        internal sealed class _ : Sink<float?>, IObserver<float?>
+        internal sealed class _ : IdentitySink<float?>
         {
             private double _sum; // NOTE: Uses a different accumulator type (double), conform LINQ to Objects.
             private long _count;
@@ -422,7 +369,7 @@ namespace System.Reactive.Linq.ObservableImpl
                 _count = 0L;
             }
 
-            public void OnNext(float? value)
+            public override void OnNext(float? value)
             {
                 try
                 {
@@ -437,30 +384,22 @@ namespace System.Reactive.Linq.ObservableImpl
                 }
                 catch (Exception ex)
                 {
-                    base._observer.OnError(ex);
-                    base.Dispose();
+                    ForwardOnError(ex);
                 }
             }
 
-            public void OnError(Exception error)
-            {
-                base._observer.OnError(error);
-                base.Dispose();
-            }
-
-            public void OnCompleted()
+            public override void OnCompleted()
             {
                 if (_count > 0)
                 {
-                    base._observer.OnNext((float)(_sum / _count));
+                    ForwardOnNext((float)(_sum / _count));
                 }
                 else
                 {
-                    base._observer.OnNext(null);
+                    ForwardOnNext(null);
                 }
 
-                base._observer.OnCompleted();
-                base.Dispose();
+                ForwardOnCompleted();
             }
         }
     }
@@ -478,7 +417,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
         protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-        internal sealed class _ : Sink<decimal?>, IObserver<decimal?>
+        internal sealed class _ : IdentitySink<decimal?>
         {
             private decimal _sum;
             private long _count;
@@ -490,7 +429,7 @@ namespace System.Reactive.Linq.ObservableImpl
                 _count = 0L;
             }
 
-            public void OnNext(decimal? value)
+            public override void OnNext(decimal? value)
             {
                 try
                 {
@@ -505,30 +444,22 @@ namespace System.Reactive.Linq.ObservableImpl
                 }
                 catch (Exception ex)
                 {
-                    base._observer.OnError(ex);
-                    base.Dispose();
+                    ForwardOnError(ex);
                 }
             }
 
-            public void OnError(Exception error)
-            {
-                base._observer.OnError(error);
-                base.Dispose();
-            }
-
-            public void OnCompleted()
+            public override void OnCompleted()
             {
                 if (_count > 0)
                 {
-                    base._observer.OnNext(_sum / _count);
+                    ForwardOnNext(_sum / _count);
                 }
                 else
                 {
-                    base._observer.OnNext(null);
+                    ForwardOnNext(null);
                 }
 
-                base._observer.OnCompleted();
-                base.Dispose();
+                ForwardOnCompleted();
             }
         }
     }
@@ -546,7 +477,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
         protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-        internal sealed class _ : Sink<double?>, IObserver<int?>
+        internal sealed class _ : Sink<int?, double?> 
         {
             private long _sum;
             private long _count;
@@ -558,7 +489,7 @@ namespace System.Reactive.Linq.ObservableImpl
                 _count = 0L;
             }
 
-            public void OnNext(int? value)
+            public override void OnNext(int? value)
             {
                 try
                 {
@@ -573,30 +504,22 @@ namespace System.Reactive.Linq.ObservableImpl
                 }
                 catch (Exception ex)
                 {
-                    base._observer.OnError(ex);
-                    base.Dispose();
+                    ForwardOnError(ex);
                 }
             }
 
-            public void OnError(Exception error)
-            {
-                base._observer.OnError(error);
-                base.Dispose();
-            }
-
-            public void OnCompleted()
+            public override void OnCompleted()
             {
                 if (_count > 0)
                 {
-                    base._observer.OnNext((double)_sum / _count);
+                    ForwardOnNext((double)_sum / _count);
                 }
                 else
                 {
-                    base._observer.OnNext(null);
+                    ForwardOnNext(null);
                 }
 
-                base._observer.OnCompleted();
-                base.Dispose();
+                ForwardOnCompleted();
             }
         }
     }
@@ -614,7 +537,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
         protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-        internal sealed class _ : Sink<double?>, IObserver<long?>
+        internal sealed class _ : Sink<long?, double?> 
         {
             private long _sum;
             private long _count;
@@ -626,7 +549,7 @@ namespace System.Reactive.Linq.ObservableImpl
                 _count = 0L;
             }
 
-            public void OnNext(long? value)
+            public override void OnNext(long? value)
             {
                 try
                 {
@@ -641,30 +564,22 @@ namespace System.Reactive.Linq.ObservableImpl
                 }
                 catch (Exception ex)
                 {
-                    base._observer.OnError(ex);
-                    base.Dispose();
+                    ForwardOnError(ex);
                 }
             }
 
-            public void OnError(Exception error)
-            {
-                base._observer.OnError(error);
-                base.Dispose();
-            }
-
-            public void OnCompleted()
+            public override void OnCompleted()
             {
                 if (_count > 0)
                 {
-                    base._observer.OnNext((double)_sum / _count);
+                    ForwardOnNext((double)_sum / _count);
                 }
                 else
                 {
-                    base._observer.OnNext(null);
+                    ForwardOnNext(null);
                 }
 
-                base._observer.OnCompleted();
-                base.Dispose();
+                ForwardOnCompleted();
             }
         }
     }

+ 50 - 63
Rx.NET/Source/src/System.Reactive/Linq/Observable/Buffer.cs

@@ -27,7 +27,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
             protected override IDisposable Run(_ sink) => sink.Run(_source);
 
-            internal sealed class _ : Sink<IList<TSource>>, IObserver<TSource>
+            internal sealed class _ : Sink<TSource, IList<TSource>> 
             {
                 private readonly Queue<IList<TSource>> _queue = new Queue<IList<TSource>>();
 
@@ -57,7 +57,7 @@ namespace System.Reactive.Linq.ObservableImpl
                     _queue.Enqueue(s);
                 }
 
-                public void OnNext(TSource value)
+                public override void OnNext(TSource value)
                 {
                     foreach (var s in _queue)
                         s.Add(value);
@@ -67,7 +67,7 @@ namespace System.Reactive.Linq.ObservableImpl
                     {
                         var s = _queue.Dequeue();
                         if (s.Count > 0)
-                            base._observer.OnNext(s);
+                            ForwardOnNext(s);
                     }
 
                     _n++;
@@ -75,26 +75,24 @@ namespace System.Reactive.Linq.ObservableImpl
                         CreateWindow();
                 }
 
-                public void OnError(Exception error)
+                public override void OnError(Exception error)
                 {
                     while (_queue.Count > 0)
                         _queue.Dequeue().Clear();
 
-                    base._observer.OnError(error);
-                    base.Dispose();
+                    ForwardOnError(error);
                 }
 
-                public void OnCompleted()
+                public override void OnCompleted()
                 {
                     while (_queue.Count > 0)
                     {
                         var s = _queue.Dequeue();
                         if (s.Count > 0)
-                            base._observer.OnNext(s);
+                            ForwardOnNext(s);
                     }
 
-                    base._observer.OnCompleted();
-                    base.Dispose();
+                    ForwardOnCompleted();
                 }
             }
         }
@@ -119,7 +117,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
             protected override IDisposable Run(_ sink) => sink.Run(this);
 
-            internal sealed class _ : Sink<IList<TSource>>, IObserver<TSource>
+            internal sealed class _ : Sink<TSource, IList<TSource>> 
             {
                 private readonly TimeSpan _timeShift;
                 private readonly IScheduler _scheduler;
@@ -207,7 +205,7 @@ namespace System.Reactive.Linq.ObservableImpl
                         if (state.isSpan)
                         {
                             var s = _q.Dequeue();
-                            base._observer.OnNext(s);
+                            ForwardOnNext(s);
                         }
 
                         if (state.isShift)
@@ -221,7 +219,7 @@ namespace System.Reactive.Linq.ObservableImpl
                     return Disposable.Empty;
                 }
 
-                public void OnNext(TSource value)
+                public override void OnNext(TSource value)
                 {
                     lock (_gate)
                     {
@@ -230,27 +228,25 @@ namespace System.Reactive.Linq.ObservableImpl
                     }
                 }
 
-                public void OnError(Exception error)
+                public override void OnError(Exception error)
                 {
                     lock (_gate)
                     {
                         while (_q.Count > 0)
                             _q.Dequeue().Clear();
 
-                        base._observer.OnError(error);
-                        base.Dispose();
+                        ForwardOnError(error);
                     }
                 }
 
-                public void OnCompleted()
+                public override void OnCompleted()
                 {
                     lock (_gate)
                     {
                         while (_q.Count > 0)
-                            base._observer.OnNext(_q.Dequeue());
+                            ForwardOnNext(_q.Dequeue());
 
-                        base._observer.OnCompleted();
-                        base.Dispose();
+                        ForwardOnCompleted();
                     }
                 }
             }
@@ -274,7 +270,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
             protected override IDisposable Run(_ sink) => sink.Run(this);
 
-            internal sealed class _ : Sink<IList<TSource>>, IObserver<TSource>
+            internal sealed class _ : Sink<TSource, IList<TSource>> 
             {
                 private readonly object _gate = new object();
 
@@ -299,12 +295,12 @@ namespace System.Reactive.Linq.ObservableImpl
                 {
                     lock (_gate)
                     {
-                        base._observer.OnNext(_list);
+                        ForwardOnNext(_list);
                         _list = new List<TSource>();
                     }
                 }
 
-                public void OnNext(TSource value)
+                public override void OnNext(TSource value)
                 {
                     lock (_gate)
                     {
@@ -312,24 +308,22 @@ namespace System.Reactive.Linq.ObservableImpl
                     }
                 }
 
-                public void OnError(Exception error)
+                public override void OnError(Exception error)
                 {
                     lock (_gate)
                     {
                         _list.Clear();
 
-                        base._observer.OnError(error);
-                        base.Dispose();
+                        ForwardOnError(error);
                     }
                 }
 
-                public void OnCompleted()
+                public override void OnCompleted()
                 {
                     lock (_gate)
                     {
-                        base._observer.OnNext(_list);
-                        base._observer.OnCompleted();
-                        base.Dispose();
+                        ForwardOnNext(_list);
+                        ForwardOnCompleted();
                     }
                 }
             }
@@ -354,7 +348,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
             protected override IDisposable Run(_ sink) => sink.Run();
 
-            internal sealed class _ : Sink<IList<TSource>>, IObserver<TSource>
+            internal sealed class _ : Sink<TSource, IList<TSource>> 
             {
                 private readonly Ferry _parent;
 
@@ -407,7 +401,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
                         var res = _s;
                         _s = new List<TSource>();
-                        base._observer.OnNext(res);
+                        ForwardOnNext(res);
 
                         CreateTimer(newId);
                     }
@@ -415,7 +409,7 @@ namespace System.Reactive.Linq.ObservableImpl
                     return d;
                 }
 
-                public void OnNext(TSource value)
+                public override void OnNext(TSource value)
                 {
                     var newWindow = false;
                     var newId = 0;
@@ -433,7 +427,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
                             var res = _s;
                             _s = new List<TSource>();
-                            base._observer.OnNext(res);
+                            ForwardOnNext(res);
                         }
 
                         if (newWindow)
@@ -441,23 +435,21 @@ namespace System.Reactive.Linq.ObservableImpl
                     }
                 }
 
-                public void OnError(Exception error)
+                public override void OnError(Exception error)
                 {
                     lock (_gate)
                     {
                         _s.Clear();
-                        base._observer.OnError(error);
-                        base.Dispose();
+                        ForwardOnError(error);
                     }
                 }
 
-                public void OnCompleted()
+                public override void OnCompleted()
                 {
                     lock (_gate)
                     {
-                        base._observer.OnNext(_s);
-                        base._observer.OnCompleted();
-                        base.Dispose();
+                        ForwardOnNext(_s);
+                        ForwardOnCompleted();
                     }
                 }
             }
@@ -481,7 +473,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
             protected override IDisposable Run(_ sink) => sink.Run(_source);
 
-            internal sealed class _ : Sink<IList<TSource>>, IObserver<TSource>
+            internal sealed class _ : Sink<TSource, IList<TSource>> 
             {
                 private readonly object _gate = new object();
                 private readonly AsyncLock _bufferGate = new AsyncLock();
@@ -519,8 +511,7 @@ namespace System.Reactive.Linq.ObservableImpl
                     {
                         lock (_gate)
                         {
-                            base._observer.OnError(exception);
-                            base.Dispose();
+                            ForwardOnError(exception);
                         }
                         return;
                     }
@@ -538,7 +529,7 @@ namespace System.Reactive.Linq.ObservableImpl
                     {
                         var res = _buffer;
                         _buffer = new List<TSource>();
-                        base._observer.OnNext(res);
+                        ForwardOnNext(res);
                     }
 
                     _bufferGate.Wait(CreateBufferClose);
@@ -571,7 +562,7 @@ namespace System.Reactive.Linq.ObservableImpl
                     }
                 }
 
-                public void OnNext(TSource value)
+                public override void OnNext(TSource value)
                 {
                     lock (_gate)
                     {
@@ -579,23 +570,21 @@ namespace System.Reactive.Linq.ObservableImpl
                     }
                 }
 
-                public void OnError(Exception error)
+                public override void OnError(Exception error)
                 {
                     lock (_gate)
                     {
                         _buffer.Clear();
-                        base._observer.OnError(error);
-                        base.Dispose();
+                        ForwardOnError(error);
                     }
                 }
 
-                public void OnCompleted()
+                public override void OnCompleted()
                 {
                     lock (_gate)
                     {
-                        base._observer.OnNext(_buffer);
-                        base._observer.OnCompleted();
-                        base.Dispose();
+                        ForwardOnNext(_buffer);
+                        ForwardOnCompleted();
                     }
                 }
             }
@@ -616,7 +605,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
             protected override IDisposable Run(_ sink) => sink.Run(this);
 
-            internal sealed class _ : Sink<IList<TSource>>, IObserver<TSource>
+            internal sealed class _ : Sink<TSource, IList<TSource>> 
             {
                 private readonly object _gate = new object();
 
@@ -652,7 +641,7 @@ namespace System.Reactive.Linq.ObservableImpl
                         {
                             var res = _parent._buffer;
                             _parent._buffer = new List<TSource>();
-                            _parent._observer.OnNext(res);
+                            _parent.ForwardOnNext(res);
                         }
                     }
 
@@ -667,7 +656,7 @@ namespace System.Reactive.Linq.ObservableImpl
                     }
                 }
 
-                public void OnNext(TSource value)
+                public override void OnNext(TSource value)
                 {
                     lock (_gate)
                     {
@@ -675,23 +664,21 @@ namespace System.Reactive.Linq.ObservableImpl
                     }
                 }
 
-                public void OnError(Exception error)
+                public override void OnError(Exception error)
                 {
                     lock (_gate)
                     {
                         _buffer.Clear();
-                        base._observer.OnError(error);
-                        base.Dispose();
+                        ForwardOnError(error);
                     }
                 }
 
-                public void OnCompleted()
+                public override void OnCompleted()
                 {
                     lock (_gate)
                     {
-                        base._observer.OnNext(_buffer);
-                        base._observer.OnCompleted();
-                        base.Dispose();
+                        ForwardOnNext(_buffer);
+                        ForwardOnCompleted();
                     }
                 }
             }

+ 2 - 20
Rx.NET/Source/src/System.Reactive/Linq/Observable/Case.cs

@@ -32,7 +32,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
         protected override IDisposable Run(_ sink) => sink.Run(this);
 
-        internal sealed class _ : Sink<TResult>, IObserver<TResult>
+        internal sealed class _ : IdentitySink<TResult>
         {
             public _(IObserver<TResult> observer, IDisposable cancel)
                 : base(observer, cancel)
@@ -48,30 +48,12 @@ namespace System.Reactive.Linq.ObservableImpl
                 }
                 catch (Exception exception)
                 {
-                    base._observer.OnError(exception);
-                    base.Dispose();
+                    ForwardOnError(exception);
                     return Disposable.Empty;
                 }
 
                 return result.SubscribeSafe(this);
             }
-
-            public void OnNext(TResult value)
-            {
-                base._observer.OnNext(value);
-            }
-
-            public void OnError(Exception error)
-            {
-                base._observer.OnError(error);
-                base.Dispose();
-            }
-
-            public void OnCompleted()
-            {
-                base._observer.OnCompleted();
-                base.Dispose();
-            }
         }
     }
 }

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

@@ -17,14 +17,14 @@ namespace System.Reactive.Linq.ObservableImpl
 
         protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-        internal sealed class _ : Sink<TResult>, IObserver<TSource>
+        internal sealed class _ : Sink<TSource, TResult> 
         {
             public _(IObserver<TResult> observer, IDisposable cancel)
                 : base(observer, cancel)
             {
             }
 
-            public void OnNext(TSource value)
+            public override void OnNext(TSource value)
             {
                 var result = default(TResult);
                 try
@@ -33,24 +33,11 @@ namespace System.Reactive.Linq.ObservableImpl
                 }
                 catch (Exception exception)
                 {
-                    base._observer.OnError(exception);
-                    base.Dispose();
+                    ForwardOnError(exception);
                     return;
                 }
 
-                base._observer.OnNext(result);
-            }
-
-            public void OnError(Exception error)
-            {
-                base._observer.OnError(error);
-                base.Dispose();
-            }
-
-            public void OnCompleted()
-            {
-                base._observer.OnCompleted();
-                base.Dispose();
+                ForwardOnNext(result);
             }
         }
     }

+ 9 - 37
Rx.NET/Source/src/System.Reactive/Linq/Observable/Catch.cs

@@ -35,11 +35,6 @@ namespace System.Reactive.Linq.ObservableImpl
                 return null;
             }
 
-            public override void OnNext(TSource value)
-            {
-                base._observer.OnNext(value);
-            }
-
             private Exception _lastException;
 
             public override void OnError(Exception error)
@@ -48,20 +43,12 @@ namespace System.Reactive.Linq.ObservableImpl
                 Recurse();
             }
 
-            public override void OnCompleted()
-            {
-                base._observer.OnCompleted();
-                base.Dispose();
-            }
-
             protected override void Done()
             {
                 if (_lastException != null)
-                    base._observer.OnError(_lastException);
+                    ForwardOnError(_lastException);
                 else
-                    base._observer.OnCompleted();
-
-                base.Dispose();
+                    ForwardOnCompleted();
             }
 
             protected override bool Fail(Exception error)
@@ -92,7 +79,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
         protected override IDisposable Run(_ sink) => sink.Run(_source);
 
-        internal sealed class _ : Sink<TSource>, IObserver<TSource>
+        internal sealed class _ : IdentitySink<TSource>
         {
             private readonly Func<TException, IObservable<TSource>> _handler;
 
@@ -115,12 +102,7 @@ namespace System.Reactive.Linq.ObservableImpl
                 return _subscription;
             }
 
-            public void OnNext(TSource value)
-            {
-                base._observer.OnNext(value);
-            }
-
-            public void OnError(Exception error)
+            public override void OnError(Exception error)
             {
                 if (error is TException e)
                 {
@@ -131,8 +113,7 @@ namespace System.Reactive.Linq.ObservableImpl
                     }
                     catch (Exception ex)
                     {
-                        base._observer.OnError(ex);
-                        base.Dispose();
+                        ForwardOnError(ex);
                         return;
                     }
 
@@ -142,17 +123,10 @@ namespace System.Reactive.Linq.ObservableImpl
                 }
                 else
                 {
-                    base._observer.OnError(error);
-                    base.Dispose();
+                    ForwardOnError(error);
                 }
             }
 
-            public void OnCompleted()
-            {
-                base._observer.OnCompleted();
-                base.Dispose();
-            }
-
             private sealed class HandlerObserver : IObserver<TSource>
             {
                 private readonly _ _parent;
@@ -164,19 +138,17 @@ namespace System.Reactive.Linq.ObservableImpl
 
                 public void OnNext(TSource value)
                 {
-                    _parent._observer.OnNext(value);
+                    _parent.ForwardOnNext(value);
                 }
 
                 public void OnError(Exception error)
                 {
-                    _parent._observer.OnError(error);
-                    _parent.Dispose();
+                    _parent.ForwardOnError(error);
                 }
 
                 public void OnCompleted()
                 {
-                    _parent._observer.OnCompleted();
-                    _parent.Dispose();
+                    _parent.ForwardOnCompleted();
                 }
             }
         }

+ 25 - 40
Rx.NET/Source/src/System.Reactive/Linq/Observable/CombineLatest.cs

@@ -28,7 +28,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
         protected override IDisposable Run(_ sink) => sink.Run(_first, _second);
 
-        internal sealed class _ : Sink<TResult>
+        internal sealed class _ : IdentitySink<TResult>
         {
             private readonly Func<TFirst, TSecond, TResult> _resultSelector;
 
@@ -93,17 +93,15 @@ namespace System.Reactive.Linq.ObservableImpl
                             }
                             catch (Exception ex)
                             {
-                                _parent._observer.OnError(ex);
-                                _parent.Dispose();
+                                _parent.ForwardOnError(ex);
                                 return;
                             }
 
-                            _parent._observer.OnNext(res);
+                            _parent.ForwardOnNext(res);
                         }
                         else if (_other.Done)
                         {
-                            _parent._observer.OnCompleted();
-                            _parent.Dispose();
+                            _parent.ForwardOnCompleted();
                             return;
                         }
                     }
@@ -113,8 +111,7 @@ namespace System.Reactive.Linq.ObservableImpl
                 {
                     lock (_parent._gate)
                     {
-                        _parent._observer.OnError(error);
-                        _parent.Dispose();
+                        _parent.ForwardOnError(error);
                     }
                 }
 
@@ -126,8 +123,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
                         if (_other.Done)
                         {
-                            _parent._observer.OnCompleted();
-                            _parent.Dispose();
+                            _parent.ForwardOnCompleted();
                             return;
                         }
                         else
@@ -172,17 +168,15 @@ namespace System.Reactive.Linq.ObservableImpl
                             }
                             catch (Exception ex)
                             {
-                                _parent._observer.OnError(ex);
-                                _parent.Dispose();
+                                _parent.ForwardOnError(ex);
                                 return;
                             }
 
-                            _parent._observer.OnNext(res);
+                            _parent.ForwardOnNext(res);
                         }
                         else if (_other.Done)
                         {
-                            _parent._observer.OnCompleted();
-                            _parent.Dispose();
+                            _parent.ForwardOnCompleted();
                             return;
                         }
                     }
@@ -192,8 +186,7 @@ namespace System.Reactive.Linq.ObservableImpl
                 {
                     lock (_parent._gate)
                     {
-                        _parent._observer.OnError(error);
-                        _parent.Dispose();
+                        _parent.ForwardOnError(error);
                     }
                 }
 
@@ -205,8 +198,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
                         if (_other.Done)
                         {
-                            _parent._observer.OnCompleted();
-                            _parent.Dispose();
+                            _parent.ForwardOnCompleted();
                             return;
                         }
                         else
@@ -232,7 +224,7 @@ namespace System.Reactive.Linq.ObservableImpl
         void Done(int index);
     }
 
-    internal abstract class CombineLatestSink<TResult> : Sink<TResult>, ICombineLatest
+    internal abstract class CombineLatestSink<TResult> : IdentitySink<TResult>, ICombineLatest
     {
         protected readonly object _gate;
 
@@ -277,12 +269,12 @@ namespace System.Reactive.Linq.ObservableImpl
                 }
                 catch (Exception ex)
                 {
-                    base._observer.OnError(ex);
-                    base.Dispose();
+                    ForwardOnError(ex);
+
                     return;
                 }
 
-                base._observer.OnNext(res);
+                ForwardOnNext(res);
             }
             else
             {
@@ -298,8 +290,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
                 if (allOthersDone)
                 {
-                    base._observer.OnCompleted();
-                    base.Dispose();
+                    ForwardOnCompleted();
                 }
             }
         }
@@ -308,8 +299,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
         public void Fail(Exception error)
         {
-            base._observer.OnError(error);
-            base.Dispose();
+            ForwardOnError(error);
         }
 
         public void Done(int index)
@@ -328,8 +318,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
             if (allDone)
             {
-                base._observer.OnCompleted();
-                base.Dispose();
+                ForwardOnCompleted();
                 return;
             }
         }
@@ -404,7 +393,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
         protected override IDisposable Run(_ sink) => sink.Run(_sources);
 
-        internal sealed class _ : Sink<TResult>
+        internal sealed class _ : IdentitySink<TResult>
         {
             private readonly Func<IList<TSource>, TResult> _resultSelector;
 
@@ -471,28 +460,25 @@ namespace System.Reactive.Linq.ObservableImpl
                         }
                         catch (Exception ex)
                         {
-                            base._observer.OnError(ex);
-                            base.Dispose();
+                            ForwardOnError(ex);
                             return;
                         }
 
-                        _observer.OnNext(res);
+                        ForwardOnNext(res);
                     }
                     else if (_isDone.AllExcept(index))
                     {
-                        base._observer.OnCompleted();
-                        base.Dispose();
+                        ForwardOnCompleted();
                         return;
                     }
                 }
             }
 
-            private void OnError(Exception error)
+            private new void OnError(Exception error)
             {
                 lock (_gate)
                 {
-                    base._observer.OnError(error);
-                    base.Dispose();
+                    ForwardOnError(error);
                 }
             }
 
@@ -504,8 +490,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
                     if (_isDone.All())
                     {
-                        base._observer.OnCompleted();
-                        base.Dispose();
+                        ForwardOnCompleted();
                         return;
                     }
                     else

+ 0 - 11
Rx.NET/Source/src/System.Reactive/Linq/Observable/Concat.cs

@@ -27,17 +27,6 @@ namespace System.Reactive.Linq.ObservableImpl
                 : base(observer, cancel)
             {
             }
-
-            public override void OnNext(TSource value)
-            {
-                base._observer.OnNext(value);
-            }
-
-            public override void OnError(Exception error)
-            {
-                base._observer.OnError(error);
-                base.Dispose();
-            }
         }
     }
 }

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

@@ -23,7 +23,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
         protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-        internal sealed class _ : Sink<bool>, IObserver<TSource>
+        internal sealed class _ : Sink<TSource, bool> 
         {
             private readonly TSource _value;
             private readonly IEqualityComparer<TSource> _comparer;
@@ -35,7 +35,7 @@ namespace System.Reactive.Linq.ObservableImpl
                 _comparer = parent._comparer;
             }
 
-            public void OnNext(TSource value)
+            public override void OnNext(TSource value)
             {
                 var res = false;
                 try
@@ -44,30 +44,21 @@ namespace System.Reactive.Linq.ObservableImpl
                 }
                 catch (Exception ex)
                 {
-                    base._observer.OnError(ex);
-                    base.Dispose();
+                    ForwardOnError(ex);
                     return;
                 }
 
                 if (res)
                 {
-                    base._observer.OnNext(true);
-                    base._observer.OnCompleted();
-                    base.Dispose();
+                    ForwardOnNext(true);
+                    ForwardOnCompleted();
                 }
             }
 
-            public void OnError(Exception error)
+            public override void OnCompleted()
             {
-                base._observer.OnError(error);
-                base.Dispose();
-            }
-
-            public void OnCompleted()
-            {
-                base._observer.OnNext(false);
-                base._observer.OnCompleted();
-                base.Dispose();
+                ForwardOnNext(false);
+                ForwardOnCompleted();
             }
         }
     }

+ 12 - 28
Rx.NET/Source/src/System.Reactive/Linq/Observable/Count.cs

@@ -19,7 +19,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
             protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-            internal sealed class _ : Sink<int>, IObserver<TSource>
+            internal sealed class _ : Sink<TSource, int> 
             {
                 private int _count;
 
@@ -29,7 +29,7 @@ namespace System.Reactive.Linq.ObservableImpl
                     _count = 0;
                 }
 
-                public void OnNext(TSource value)
+                public override void OnNext(TSource value)
                 {
                     try
                     {
@@ -40,22 +40,14 @@ namespace System.Reactive.Linq.ObservableImpl
                     }
                     catch (Exception ex)
                     {
-                        base._observer.OnError(ex);
-                        base.Dispose();
+                        ForwardOnError(ex);
                     }
                 }
 
-                public void OnError(Exception error)
+                public override void OnCompleted()
                 {
-                    base._observer.OnError(error);
-                    base.Dispose();
-                }
-
-                public void OnCompleted()
-                {
-                    base._observer.OnNext(_count);
-                    base._observer.OnCompleted();
-                    base.Dispose();
+                    ForwardOnNext(_count);
+                    ForwardOnCompleted();
                 }
             }
         }
@@ -75,7 +67,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
             protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-            internal sealed class _ : Sink<int>, IObserver<TSource>
+            internal sealed class _ : Sink<TSource, int> 
             {
                 private readonly Func<TSource, bool> _predicate;
                 private int _count;
@@ -87,7 +79,7 @@ namespace System.Reactive.Linq.ObservableImpl
                     _count = 0;
                 }
 
-                public void OnNext(TSource value)
+                public override void OnNext(TSource value)
                 {
                     try
                     {
@@ -101,22 +93,14 @@ namespace System.Reactive.Linq.ObservableImpl
                     }
                     catch (Exception ex)
                     {
-                        base._observer.OnError(ex);
-                        base.Dispose();
+                        ForwardOnError(ex);
                     }
                 }
 
-                public void OnError(Exception error)
-                {
-                    base._observer.OnError(error);
-                    base.Dispose();
-                }
-
-                public void OnCompleted()
+                public override void OnCompleted()
                 {
-                    base._observer.OnNext(_count);
-                    base._observer.OnCompleted();
-                    base.Dispose();
+                    ForwardOnNext(_count);
+                    ForwardOnCompleted();
                 }
             }
         }

+ 7 - 13
Rx.NET/Source/src/System.Reactive/Linq/Observable/DefaultIfEmpty.cs

@@ -19,7 +19,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
         protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-        internal sealed class _ : Sink<TSource>, IObserver<TSource>
+        internal sealed class _ : IdentitySink<TSource>
         {
             private readonly TSource _defaultValue;
             private bool _found;
@@ -31,24 +31,18 @@ namespace System.Reactive.Linq.ObservableImpl
                 _found = false;
             }
 
-            public void OnNext(TSource value)
+            public override void OnNext(TSource value)
             {
                 _found = true;
-                base._observer.OnNext(value);
+                ForwardOnNext(value);
             }
 
-            public void OnError(Exception error)
-            {
-                base._observer.OnError(error);
-                base.Dispose();
-            }
-
-            public void OnCompleted()
+            public override void OnCompleted()
             {
                 if (!_found)
-                    base._observer.OnNext(_defaultValue);
-                base._observer.OnCompleted();
-                base.Dispose();
+                    ForwardOnNext(_defaultValue);
+
+                ForwardOnCompleted();
             }
         }
     }

+ 2 - 20
Rx.NET/Source/src/System.Reactive/Linq/Observable/Defer.cs

@@ -21,7 +21,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
         public IObservable<TValue> Eval() => _observableFactory();
 
-        internal sealed class _ : Sink<TValue>, IObserver<TValue>
+        internal sealed class _ : IdentitySink<TValue>
         {
             private readonly Func<IObservable<TValue>> _observableFactory;
 
@@ -40,30 +40,12 @@ namespace System.Reactive.Linq.ObservableImpl
                 }
                 catch (Exception exception)
                 {
-                    base._observer.OnError(exception);
-                    base.Dispose();
+                    ForwardOnError(exception);
                     return Disposable.Empty;
                 }
 
                 return result.SubscribeSafe(this);
             }
-
-            public void OnNext(TValue value)
-            {
-                base._observer.OnNext(value);
-            }
-
-            public void OnError(Exception error)
-            {
-                base._observer.OnError(error);
-                base.Dispose();
-            }
-
-            public void OnCompleted()
-            {
-                base._observer.OnCompleted();
-                base.Dispose();
-            }
         }
     }
 }

+ 19 - 33
Rx.NET/Source/src/System.Reactive/Linq/Observable/Delay.cs

@@ -23,17 +23,13 @@ namespace System.Reactive.Linq.ObservableImpl
                 _scheduler = scheduler;
             }
 
-            internal abstract class _ : Sink<TSource>, IObserver<TSource>
+            internal abstract class _ : IdentitySink<TSource>
             {
                 public _(IObserver<TSource> observer, IDisposable cancel)
                     : base(observer, cancel)
                 {
                 }
 
-                public abstract void OnCompleted();
-                public abstract void OnError(Exception error);
-                public abstract void OnNext(TSource value);
-
                 public abstract IDisposable Run(TParent parent);
             }
 
@@ -124,8 +120,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
                     if (shouldRun)
                     {
-                        base._observer.OnError(error);
-                        base.Dispose();
+                        ForwardOnError(error);
                     }
                 }
 
@@ -234,20 +229,18 @@ namespace System.Reactive.Linq.ObservableImpl
 
                         if (hasValue)
                         {
-                            base._observer.OnNext(value);
+                            ForwardOnNext(value);
                             shouldYield = true;
                         }
                         else
                         {
                             if (hasCompleted)
                             {
-                                base._observer.OnCompleted();
-                                base.Dispose();
+                                ForwardOnCompleted();
                             }
                             else if (hasFailed)
                             {
-                                base._observer.OnError(error);
-                                base.Dispose();
+                                ForwardOnError(error);
                             }
                             else if (shouldRecurse)
                             {
@@ -435,19 +428,17 @@ namespace System.Reactive.Linq.ObservableImpl
 
                         if (hasValue)
                         {
-                            base._observer.OnNext(value);
+                            ForwardOnNext(value);
                         }
                         else
                         {
                             if (hasCompleted)
                             {
-                                base._observer.OnCompleted();
-                                base.Dispose();
+                                ForwardOnCompleted();
                             }
                             else if (hasFailed)
                             {
-                                base._observer.OnError(error);
-                                base.Dispose();
+                                ForwardOnError(error);
                             }
 
                             return;
@@ -611,7 +602,7 @@ namespace System.Reactive.Linq.ObservableImpl
                 _source = source;
             }
 
-            internal abstract class _ : Sink<TSource>, IObserver<TSource>
+            internal abstract class _ : IdentitySink<TSource>
             {
                 private readonly CompositeDisposable _delays = new CompositeDisposable();
                 private object _gate = new object();
@@ -638,7 +629,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
                 protected abstract IDisposable RunCore(TParent parent);
 
-                public void OnNext(TSource value)
+                public override void OnNext(TSource value)
                 {
                     var delay = default(IObservable<TDelay>);
                     try
@@ -649,8 +640,7 @@ namespace System.Reactive.Linq.ObservableImpl
                     {
                         lock (_gate)
                         {
-                            base._observer.OnError(error);
-                            base.Dispose();
+                            ForwardOnError(error);
                         }
 
                         return;
@@ -661,16 +651,15 @@ namespace System.Reactive.Linq.ObservableImpl
                     d.Disposable = delay.SubscribeSafe(new DelayObserver(this, value, d));
                 }
 
-                public void OnError(Exception error)
+                public override void OnError(Exception error)
                 {
                     lock (_gate)
                     {
-                        base._observer.OnError(error);
-                        base.Dispose();
+                        ForwardOnError(error);
                     }
                 }
 
-                public void OnCompleted()
+                public override void OnCompleted()
                 {
                     lock (_gate)
                     {
@@ -685,8 +674,7 @@ namespace System.Reactive.Linq.ObservableImpl
                 {
                     if (_atEnd && _delays.Count == 0)
                     {
-                        base._observer.OnCompleted();
-                        base.Dispose();
+                        ForwardOnCompleted();
                     }
                 }
 
@@ -707,7 +695,7 @@ namespace System.Reactive.Linq.ObservableImpl
                     {
                         lock (_parent._gate)
                         {
-                            _parent._observer.OnNext(_value);
+                            _parent.ForwardOnNext(_value);
 
                             _parent._delays.Remove(_self);
                             _parent.CheckDone();
@@ -718,8 +706,7 @@ namespace System.Reactive.Linq.ObservableImpl
                     {
                         lock (_parent._gate)
                         {
-                            _parent._observer.OnError(error);
-                            _parent.Dispose();
+                            _parent.ForwardOnError(error);
                         }
                     }
 
@@ -727,7 +714,7 @@ namespace System.Reactive.Linq.ObservableImpl
                     {
                         lock (_parent._gate)
                         {
-                            _parent._observer.OnNext(_value);
+                            _parent.ForwardOnNext(_value);
 
                             _parent._delays.Remove(_self);
                             _parent.CheckDone();
@@ -814,8 +801,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
                     public void OnError(Exception error)
                     {
-                        _parent._observer.OnError(error);
-                        _parent.Dispose();
+                        _parent.ForwardOnError(error);
                     }
 
                     public void OnCompleted()

+ 1 - 18
Rx.NET/Source/src/System.Reactive/Linq/Observable/DelaySubscription.cs

@@ -52,29 +52,12 @@ namespace System.Reactive.Linq.ObservableImpl
             return _source.SubscribeSafe(sink);
         }
 
-        internal sealed class _ : Sink<TSource>, IObserver<TSource>
+        internal sealed class _ : IdentitySink<TSource>
         {
             public _(IObserver<TSource> observer, IDisposable cancel)
                 : base(observer, cancel)
             {
             }
-
-            public void OnNext(TSource value)
-            {
-                base._observer.OnNext(value);
-            }
-
-            public void OnError(Exception error)
-            {
-                base._observer.OnError(error);
-                base.Dispose();
-            }
-
-            public void OnCompleted()
-            {
-                base._observer.OnCompleted();
-                base.Dispose();
-            }
         }
     }
 }

+ 5 - 19
Rx.NET/Source/src/System.Reactive/Linq/Observable/Dematerialize.cs

@@ -17,42 +17,28 @@ namespace System.Reactive.Linq.ObservableImpl
 
         protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-        internal sealed class _ : Sink<TSource>, IObserver<Notification<TSource>>
+        internal sealed class _ : Sink<Notification<TSource>, TSource> 
         {
             public _(IObserver<TSource> observer, IDisposable cancel)
                 : base(observer, cancel)
             {
             }
 
-            public void OnNext(Notification<TSource> value)
+            public override void OnNext(Notification<TSource> value)
             {
                 switch (value.Kind)
                 {
                     case NotificationKind.OnNext:
-                        base._observer.OnNext(value.Value);
+                        ForwardOnNext(value.Value);
                         break;
                     case NotificationKind.OnError:
-                        base._observer.OnError(value.Exception);
-                        base.Dispose();
+                        ForwardOnError(value.Exception);
                         break;
                     case NotificationKind.OnCompleted:
-                        base._observer.OnCompleted();
-                        base.Dispose();
+                        ForwardOnCompleted();
                         break;
                 }
             }
-
-            public void OnError(Exception error)
-            {
-                base._observer.OnError(error);
-                base.Dispose();
-            }
-
-            public void OnCompleted()
-            {
-                base._observer.OnCompleted();
-                base.Dispose();
-            }
         }
     }
 }

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

@@ -23,7 +23,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
         protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-        internal sealed class _ : Sink<TSource>, IObserver<TSource>
+        internal sealed class _ : IdentitySink<TSource>
         {
             private readonly Func<TSource, TKey> _keySelector;
             private HashSet<TKey> _hashSet;
@@ -35,7 +35,7 @@ namespace System.Reactive.Linq.ObservableImpl
                 _hashSet = new HashSet<TKey>(parent._comparer);
             }
 
-            public void OnNext(TSource value)
+            public override void OnNext(TSource value)
             {
                 var key = default(TKey);
                 var hasAdded = false;
@@ -46,25 +46,12 @@ namespace System.Reactive.Linq.ObservableImpl
                 }
                 catch (Exception exception)
                 {
-                    base._observer.OnError(exception);
-                    base.Dispose();
+                    ForwardOnError(exception);
                     return;
                 }
 
                 if (hasAdded)
-                    base._observer.OnNext(value);
-            }
-
-            public void OnError(Exception error)
-            {
-                base._observer.OnError(error);
-                base.Dispose();
-            }
-
-            public void OnCompleted()
-            {
-                base._observer.OnCompleted();
-                base.Dispose();
+                    ForwardOnNext(value);
             }
         }
     }

+ 5 - 19
Rx.NET/Source/src/System.Reactive/Linq/Observable/DistinctUntilChanged.cs

@@ -23,7 +23,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
         protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-        internal sealed class _ : Sink<TSource>, IObserver<TSource>
+        internal sealed class _ : IdentitySink<TSource>
         {
             private readonly Func<TSource, TKey> _keySelector;
             private readonly IEqualityComparer<TKey> _comparer;
@@ -41,7 +41,7 @@ namespace System.Reactive.Linq.ObservableImpl
                 _hasCurrentKey = false;
             }
 
-            public void OnNext(TSource value)
+            public override void OnNext(TSource value)
             {
                 var key = default(TKey);
                 try
@@ -50,8 +50,7 @@ namespace System.Reactive.Linq.ObservableImpl
                 }
                 catch (Exception exception)
                 {
-                    base._observer.OnError(exception);
-                    base.Dispose();
+                    ForwardOnError(exception);
                     return;
                 }
 
@@ -64,8 +63,7 @@ namespace System.Reactive.Linq.ObservableImpl
                     }
                     catch (Exception exception)
                     {
-                        base._observer.OnError(exception);
-                        base.Dispose();
+                        ForwardOnError(exception);
                         return;
                     }
                 }
@@ -74,21 +72,9 @@ namespace System.Reactive.Linq.ObservableImpl
                 {
                     _hasCurrentKey = true;
                     _currentKey = key;
-                    base._observer.OnNext(value);
+                    ForwardOnNext(value);
                 }
             }
-
-            public void OnError(Exception error)
-            {
-                base._observer.OnError(error);
-                base.Dispose();
-            }
-
-            public void OnCompleted()
-            {
-                base._observer.OnCompleted();
-                base.Dispose();
-            }
         }
     }
 }

+ 24 - 47
Rx.NET/Source/src/System.Reactive/Linq/Observable/Do.cs

@@ -21,7 +21,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
             protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-            internal sealed class _ : Sink<TSource>, IObserver<TSource>
+            internal sealed class _ : IdentitySink<TSource>
             {
                 private readonly Action<TSource> _onNext;
 
@@ -31,7 +31,7 @@ namespace System.Reactive.Linq.ObservableImpl
                     _onNext = onNext;
                 }
 
-                public void OnNext(TSource value)
+                public override void OnNext(TSource value)
                 {
                     try
                     {
@@ -39,24 +39,11 @@ namespace System.Reactive.Linq.ObservableImpl
                     }
                     catch (Exception ex)
                     {
-                        base._observer.OnError(ex);
-                        base.Dispose();
+                        ForwardOnError(ex);
                         return;
                     }
 
-                    base._observer.OnNext(value);
-                }
-
-                public void OnError(Exception error)
-                {
-                    base._observer.OnError(error);
-                    base.Dispose();
-                }
-
-                public void OnCompleted()
-                {
-                    base._observer.OnCompleted();
-                    base.Dispose();
+                    ForwardOnNext(value);
                 }
             }
         }
@@ -76,7 +63,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
             protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-            internal sealed class _ : Sink<TSource>, IObserver<TSource>
+            internal sealed class _ : IdentitySink<TSource>
             {
                 private readonly IObserver<TSource> _doObserver;
 
@@ -86,7 +73,7 @@ namespace System.Reactive.Linq.ObservableImpl
                     _doObserver = doObserver;
                 }
 
-                public void OnNext(TSource value)
+                public override void OnNext(TSource value)
                 {
                     try
                     {
@@ -94,15 +81,14 @@ namespace System.Reactive.Linq.ObservableImpl
                     }
                     catch (Exception ex)
                     {
-                        base._observer.OnError(ex);
-                        base.Dispose();
+                        ForwardOnError(ex);
                         return;
                     }
 
-                    base._observer.OnNext(value);
+                    ForwardOnNext(value);
                 }
 
-                public void OnError(Exception error)
+                public override void OnError(Exception error)
                 {
                     try
                     {
@@ -110,16 +96,14 @@ namespace System.Reactive.Linq.ObservableImpl
                     }
                     catch (Exception ex)
                     {
-                        base._observer.OnError(ex);
-                        base.Dispose();
+                        ForwardOnError(ex);
                         return;
                     }
 
-                    base._observer.OnError(error);
-                    base.Dispose();
+                    ForwardOnError(error);
                 }
 
-                public void OnCompleted()
+                public override void OnCompleted()
                 {
                     try
                     {
@@ -127,13 +111,11 @@ namespace System.Reactive.Linq.ObservableImpl
                     }
                     catch (Exception ex)
                     {
-                        base._observer.OnError(ex);
-                        base.Dispose();
+                        ForwardOnError(ex);
                         return;
                     }
 
-                    base._observer.OnCompleted();
-                    base.Dispose();
+                    ForwardOnCompleted();
                 }
             }
         }
@@ -157,7 +139,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
             protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-            internal sealed class _ : Sink<TSource>, IObserver<TSource>
+            internal sealed class _ : IdentitySink<TSource>
             {
                 // CONSIDER: This sink has a parent reference that can be considered for removal.
 
@@ -169,7 +151,7 @@ namespace System.Reactive.Linq.ObservableImpl
                     _parent = parent;
                 }
 
-                public void OnNext(TSource value)
+                public override void OnNext(TSource value)
                 {
                     try
                     {
@@ -177,15 +159,14 @@ namespace System.Reactive.Linq.ObservableImpl
                     }
                     catch (Exception ex)
                     {
-                        base._observer.OnError(ex);
-                        base.Dispose();
+                        ForwardOnError(ex);
                         return;
                     }
 
-                    base._observer.OnNext(value);
+                    ForwardOnNext(value);
                 }
 
-                public void OnError(Exception error)
+                public override void OnError(Exception error)
                 {
                     try
                     {
@@ -193,16 +174,14 @@ namespace System.Reactive.Linq.ObservableImpl
                     }
                     catch (Exception ex)
                     {
-                        base._observer.OnError(ex);
-                        base.Dispose();
+                        ForwardOnError(ex);
                         return;
                     }
 
-                    base._observer.OnError(error);
-                    base.Dispose();
+                    ForwardOnError(error);
                 }
 
-                public void OnCompleted()
+                public override void OnCompleted()
                 {
                     try
                     {
@@ -210,13 +189,11 @@ namespace System.Reactive.Linq.ObservableImpl
                     }
                     catch (Exception ex)
                     {
-                        base._observer.OnError(ex);
-                        base.Dispose();
+                        ForwardOnError(ex);
                         return;
                     }
 
-                    base._observer.OnCompleted();
-                    base.Dispose();
+                    ForwardOnCompleted();
                 }
             }
         }

+ 0 - 11
Rx.NET/Source/src/System.Reactive/Linq/Observable/DoWhile.cs

@@ -34,17 +34,6 @@ namespace System.Reactive.Linq.ObservableImpl
                 : base(observer, cancel)
             {
             }
-
-            public override void OnNext(TSource value)
-            {
-                base._observer.OnNext(value);
-            }
-
-            public override void OnError(Exception error)
-            {
-                base._observer.OnError(error);
-                base.Dispose();
-            }
         }
     }
 }

+ 6 - 14
Rx.NET/Source/src/System.Reactive/Linq/Observable/ElementAt.cs

@@ -19,7 +19,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
         protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-        internal sealed class _ : Sink<TSource>, IObserver<TSource>
+        internal sealed class _ : IdentitySink<TSource>
         {
             private int _i;
 
@@ -29,28 +29,20 @@ namespace System.Reactive.Linq.ObservableImpl
                 _i = index;
             }
 
-            public void OnNext(TSource value)
+            public override void OnNext(TSource value)
             {
                 if (_i == 0)
                 {
-                    base._observer.OnNext(value);
-                    base._observer.OnCompleted();
-                    base.Dispose();
+                    ForwardOnNext(value);
+                    ForwardOnCompleted();
                 }
 
                 _i--;
             }
 
-            public void OnError(Exception error)
+            public override void OnCompleted()
             {
-                base._observer.OnError(error);
-                base.Dispose();
-            }
-
-            public void OnCompleted()
-            {
-                base._observer.OnError(new ArgumentOutOfRangeException("index"));
-                base.Dispose();
+                ForwardOnError(new ArgumentOutOfRangeException("index"));
             }
         }
     }

+ 7 - 15
Rx.NET/Source/src/System.Reactive/Linq/Observable/ElementAtOrDefault.cs

@@ -19,7 +19,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
         protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-        internal sealed class _ : Sink<TSource>, IObserver<TSource>
+        internal sealed class _ : IdentitySink<TSource>
         {
             private int _i;
 
@@ -29,29 +29,21 @@ namespace System.Reactive.Linq.ObservableImpl
                 _i = index;
             }
 
-            public void OnNext(TSource value)
+            public override void OnNext(TSource value)
             {
                 if (_i == 0)
                 {
-                    base._observer.OnNext(value);
-                    base._observer.OnCompleted();
-                    base.Dispose();
+                    ForwardOnNext(value);
+                    ForwardOnCompleted();
                 }
 
                 _i--;
             }
 
-            public void OnError(Exception error)
+            public override void OnCompleted()
             {
-                base._observer.OnError(error);
-                base.Dispose();
-            }
-
-            public void OnCompleted()
-            {
-                base._observer.OnNext(default(TSource));
-                base._observer.OnCompleted();
-                base.Dispose();
+                ForwardOnNext(default(TSource));
+                ForwardOnCompleted();
             }
         }
     }

+ 2 - 3
Rx.NET/Source/src/System.Reactive/Linq/Observable/Empty.cs

@@ -19,7 +19,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
         protected override IDisposable Run(_ sink) => sink.Run(_scheduler);
 
-        internal sealed class _ : Sink<TResult>
+        internal sealed class _ : IdentitySink<TResult>
         {
             public _(IObserver<TResult> observer, IDisposable cancel)
                 : base(observer, cancel)
@@ -33,8 +33,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
             private void Invoke()
             {
-                base._observer.OnCompleted();
-                base.Dispose();
+                ForwardOnCompleted();
             }
         }
     }

+ 1 - 18
Rx.NET/Source/src/System.Reactive/Linq/Observable/Finally.cs

@@ -21,7 +21,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
         protected override IDisposable Run(_ sink) => sink.Run(_source);
 
-        internal sealed class _ : Sink<TSource>, IObserver<TSource>
+        internal sealed class _ : IdentitySink<TSource>
         {
             private readonly Action _finallyAction;
 
@@ -47,23 +47,6 @@ namespace System.Reactive.Linq.ObservableImpl
                     }
                 });
             }
-
-            public void OnNext(TSource value)
-            {
-                base._observer.OnNext(value);
-            }
-
-            public void OnError(Exception error)
-            {
-                base._observer.OnError(error);
-                base.Dispose();
-            }
-
-            public void OnCompleted()
-            {
-                base._observer.OnCompleted();
-                base.Dispose();
-            }
         }
     }
 }

+ 13 - 30
Rx.NET/Source/src/System.Reactive/Linq/Observable/FirstAsync.cs

@@ -19,30 +19,22 @@ namespace System.Reactive.Linq.ObservableImpl
 
             protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-            internal sealed class _ : Sink<TSource>, IObserver<TSource>
+            internal sealed class _ : IdentitySink<TSource>
             {
                 public _(IObserver<TSource> observer, IDisposable cancel)
                     : base(observer, cancel)
                 {
                 }
 
-                public void OnNext(TSource value)
+                public override void OnNext(TSource value)
                 {
-                    base._observer.OnNext(value);
-                    base._observer.OnCompleted();
-                    base.Dispose();
+                    ForwardOnNext(value);
+                    ForwardOnCompleted();
                 }
 
-                public void OnError(Exception error)
+                public override void OnCompleted()
                 {
-                    base._observer.OnError(error);
-                    base.Dispose();
-                }
-
-                public void OnCompleted()
-                {
-                    base._observer.OnError(new InvalidOperationException(Strings_Linq.NO_ELEMENTS));
-                    base.Dispose();
+                    ForwardOnError(new InvalidOperationException(Strings_Linq.NO_ELEMENTS));
                 }
             }
         }
@@ -62,7 +54,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
             protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-            internal sealed class _ : Sink<TSource>, IObserver<TSource>
+            internal sealed class _ : IdentitySink<TSource>
             {
                 private readonly Func<TSource, bool> _predicate;
 
@@ -72,7 +64,7 @@ namespace System.Reactive.Linq.ObservableImpl
                     _predicate = predicate;
                 }
 
-                public void OnNext(TSource value)
+                public override void OnNext(TSource value)
                 {
                     var b = false;
 
@@ -82,29 +74,20 @@ namespace System.Reactive.Linq.ObservableImpl
                     }
                     catch (Exception ex)
                     {
-                        base._observer.OnError(ex);
-                        base.Dispose();
+                        ForwardOnError(ex);
                         return;
                     }
 
                     if (b)
                     {
-                        base._observer.OnNext(value);
-                        base._observer.OnCompleted();
-                        base.Dispose();
+                        ForwardOnNext(value);
+                        ForwardOnCompleted();
                     }
                 }
 
-                public void OnError(Exception error)
-                {
-                    base._observer.OnError(error);
-                    base.Dispose();
-                }
-
-                public void OnCompleted()
+                public override void OnCompleted()
                 {
-                    base._observer.OnError(new InvalidOperationException(Strings_Linq.NO_MATCHING_ELEMENTS));
-                    base.Dispose();
+                    ForwardOnError(new InvalidOperationException(Strings_Linq.NO_MATCHING_ELEMENTS));
                 }
             }
         }

+ 15 - 32
Rx.NET/Source/src/System.Reactive/Linq/Observable/FirstOrDefaultAsync.cs

@@ -19,31 +19,23 @@ namespace System.Reactive.Linq.ObservableImpl
 
             protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-            internal sealed class _ : Sink<TSource>, IObserver<TSource>
+            internal sealed class _ : IdentitySink<TSource>
             {
                 public _(IObserver<TSource> observer, IDisposable cancel)
                     : base(observer, cancel)
                 {
                 }
 
-                public void OnNext(TSource value)
+                public override void OnNext(TSource value)
                 {
-                    base._observer.OnNext(value);
-                    base._observer.OnCompleted();
-                    base.Dispose();
+                    ForwardOnNext(value);
+                    ForwardOnCompleted();
                 }
 
-                public void OnError(Exception error)
+                public override void OnCompleted()
                 {
-                    base._observer.OnError(error);
-                    base.Dispose();
-                }
-
-                public void OnCompleted()
-                {
-                    base._observer.OnNext(default(TSource));
-                    base._observer.OnCompleted();
-                    base.Dispose();
+                    ForwardOnNext(default(TSource));
+                    ForwardOnCompleted();
                 }
             }
         }
@@ -63,7 +55,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
             protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-            internal sealed class _ : Sink<TSource>, IObserver<TSource>
+            internal sealed class _ : IdentitySink<TSource>
             {
                 private readonly Func<TSource, bool> _predicate;
 
@@ -73,7 +65,7 @@ namespace System.Reactive.Linq.ObservableImpl
                     _predicate = predicate;
                 }
 
-                public void OnNext(TSource value)
+                public override void OnNext(TSource value)
                 {
                     var b = false;
 
@@ -83,30 +75,21 @@ namespace System.Reactive.Linq.ObservableImpl
                     }
                     catch (Exception ex)
                     {
-                        base._observer.OnError(ex);
-                        base.Dispose();
+                        ForwardOnError(ex);
                         return;
                     }
 
                     if (b)
                     {
-                        base._observer.OnNext(value);
-                        base._observer.OnCompleted();
-                        base.Dispose();
+                        ForwardOnNext(value);
+                        ForwardOnCompleted();
                     }
                 }
 
-                public void OnError(Exception error)
-                {
-                    base._observer.OnError(error);
-                    base.Dispose();
-                }
-
-                public void OnCompleted()
+                public override void OnCompleted()
                 {
-                    base._observer.OnNext(default(TSource));
-                    base._observer.OnCompleted();
-                    base.Dispose();
+                    ForwardOnNext(default(TSource));
+                    ForwardOnCompleted();
                 }
             }
         }

+ 0 - 11
Rx.NET/Source/src/System.Reactive/Linq/Observable/For.cs

@@ -33,17 +33,6 @@ namespace System.Reactive.Linq.ObservableImpl
                 : base(observer, cancel)
             {
             }
-
-            public override void OnNext(TResult value)
-            {
-                base._observer.OnNext(value);
-            }
-
-            public override void OnError(Exception error)
-            {
-                base._observer.OnError(error);
-                base.Dispose();
-            }
         }
     }
 }

+ 15 - 24
Rx.NET/Source/src/System.Reactive/Linq/Observable/Generate.cs

@@ -30,7 +30,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
             protected override IDisposable Run(_ sink) => sink.Run();
 
-            internal sealed class _ : Sink<TResult>
+            internal sealed class _ : IdentitySink<TResult>
             {
                 // CONSIDER: This sink has a parent reference that can be considered for removal.
 
@@ -87,14 +87,13 @@ namespace System.Reactive.Linq.ObservableImpl
                         }
                         catch (Exception exception)
                         {
-                            base._observer.OnError(exception);
-                            base.Dispose();
+                            ForwardOnError(exception);
                             return;
                         }
 
                         if (hasResult)
                         {
-                            base._observer.OnNext(result);
+                            ForwardOnNext(result);
                         }
                         else
                         {
@@ -104,10 +103,8 @@ namespace System.Reactive.Linq.ObservableImpl
 
                     if (!cancel.IsDisposed)
                     {
-                        base._observer.OnCompleted();
+                        ForwardOnCompleted();
                     }
-
-                    base.Dispose();
                 }
 
                 private void LoopRec(Action recurse)
@@ -134,20 +131,18 @@ namespace System.Reactive.Linq.ObservableImpl
                     }
                     catch (Exception exception)
                     {
-                        base._observer.OnError(exception);
-                        base.Dispose();
+                        ForwardOnError(exception);
                         return;
                     }
 
                     if (hasResult)
                     {
-                        base._observer.OnNext(result);
+                        ForwardOnNext(result);
                         recurse();
                     }
                     else
                     {
-                        base._observer.OnCompleted();
-                        base.Dispose();
+                        ForwardOnCompleted();
                     }
                 }
             }
@@ -176,7 +171,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
             protected override IDisposable Run(_ sink) => sink.Run();
 
-            internal sealed class _ : Sink<TResult>
+            internal sealed class _ : IdentitySink<TResult>
             {
                 // CONSIDER: This sink has a parent reference that can be considered for removal.
 
@@ -207,7 +202,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
                     if (_hasResult)
                     {
-                        base._observer.OnNext(_result);
+                        ForwardOnNext(_result);
                     }
 
                     try
@@ -231,15 +226,13 @@ namespace System.Reactive.Linq.ObservableImpl
                     }
                     catch (Exception exception)
                     {
-                        base._observer.OnError(exception);
-                        base.Dispose();
+                        ForwardOnError(exception);
                         return Disposable.Empty;
                     }
 
                     if (!_hasResult)
                     {
-                        base._observer.OnCompleted();
-                        base.Dispose();
+                        ForwardOnCompleted();
                         return Disposable.Empty;
                     }
 
@@ -271,7 +264,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
             protected override IDisposable Run(_ sink) => sink.Run();
 
-            internal sealed class _ : Sink<TResult>
+            internal sealed class _ : IdentitySink<TResult>
             {
                 // CONSIDER: This sink has a parent reference that can be considered for removal.
 
@@ -302,7 +295,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
                     if (_hasResult)
                     {
-                        base._observer.OnNext(_result);
+                        ForwardOnNext(_result);
                     }
 
                     try
@@ -326,15 +319,13 @@ namespace System.Reactive.Linq.ObservableImpl
                     }
                     catch (Exception exception)
                     {
-                        base._observer.OnError(exception);
-                        base.Dispose();
+                        ForwardOnError(exception);
                         return Disposable.Empty;
                     }
 
                     if (!_hasResult)
                     {
-                        base._observer.OnCompleted();
-                        base.Dispose();
+                        ForwardOnCompleted();
                         return Disposable.Empty;
                     }
 

+ 7 - 9
Rx.NET/Source/src/System.Reactive/Linq/Observable/GroupBy.cs

@@ -29,7 +29,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
         protected override IDisposable Run(_ sink) => sink.Run(_source);
 
-        internal sealed class _ : Sink<IGroupedObservable<TKey, TElement>>, IObserver<TSource>
+        internal sealed class _ : Sink<TSource, IGroupedObservable<TKey, TElement>> 
         {
             private readonly Func<TSource, TKey> _keySelector;
             private readonly Func<TSource, TElement> _elementSelector;
@@ -62,7 +62,7 @@ namespace System.Reactive.Linq.ObservableImpl
                 return _refCountDisposable;
             }
 
-            public void OnNext(TSource value)
+            public override void OnNext(TSource value)
             {
                 var key = default(TKey);
                 try
@@ -126,7 +126,7 @@ namespace System.Reactive.Linq.ObservableImpl
                 if (fireNewMapEntry)
                 {
                     var group = new GroupedObservable<TKey, TElement>(key, writer, _refCountDisposable);
-                    _observer.OnNext(group);
+                    ForwardOnNext(group);
                 }
 
                 var element = default(TElement);
@@ -143,20 +143,19 @@ namespace System.Reactive.Linq.ObservableImpl
                 writer.OnNext(element);
             }
 
-            public void OnError(Exception error)
+            public override void OnError(Exception error)
             {
                 Error(error);
             }
 
-            public void OnCompleted()
+            public override void OnCompleted()
             {
                 _null?.OnCompleted();
 
                 foreach (var w in _map.Values)
                     w.OnCompleted();
 
-                base._observer.OnCompleted();
-                base.Dispose();
+                ForwardOnCompleted();
             }
 
             private void Error(Exception exception)
@@ -166,8 +165,7 @@ namespace System.Reactive.Linq.ObservableImpl
                 foreach (var w in _map.Values)
                     w.OnError(exception);
 
-                base._observer.OnError(exception);
-                base.Dispose();
+                ForwardOnError(exception);
             }
         }
     }

+ 11 - 14
Rx.NET/Source/src/System.Reactive/Linq/Observable/GroupByUntil.cs

@@ -33,8 +33,9 @@ namespace System.Reactive.Linq.ObservableImpl
 
         protected override IDisposable Run(_ sink) => sink.Run(_source);
 
-        internal sealed class _ : Sink<IGroupedObservable<TKey, TElement>>, IObserver<TSource>
+        internal sealed class _ : Sink<TSource, IGroupedObservable<TKey, TElement>> 
         {
+            private readonly object _gate = new object();
             private readonly object _nullGate = new object();
             private readonly CompositeDisposable _groupDisposable = new CompositeDisposable();
             private readonly RefCountDisposable _refCountDisposable;
@@ -71,7 +72,7 @@ namespace System.Reactive.Linq.ObservableImpl
                 return Subject.Create<TElement>(new AsyncLockObserver<TElement>(sub, new Concurrency.AsyncLock()), sub);
             }
 
-            public void OnNext(TSource value)
+            public override void OnNext(TSource value)
             {
                 var key = default(TKey);
                 try
@@ -137,8 +138,8 @@ namespace System.Reactive.Linq.ObservableImpl
                         return;
                     }
 
-                    lock (base._observer)
-                        base._observer.OnNext(group);
+                    lock (_gate)
+                        ForwardOnNext(group);
 
                     var md = new SingleAssignmentDisposable();
                     _groupDisposable.Add(md);
@@ -228,12 +229,12 @@ namespace System.Reactive.Linq.ObservableImpl
                 }
             }
 
-            public void OnError(Exception error)
+            public override void OnError(Exception error)
             {
                 Error(error);
             }
 
-            public void OnCompleted()
+            public override void OnCompleted()
             {
                 //
                 // NOTE: A race with OnCompleted triggered by a duration selector is fine when
@@ -249,10 +250,8 @@ namespace System.Reactive.Linq.ObservableImpl
                 foreach (var w in _map.Values)
                     w.OnCompleted();
 
-                lock (base._observer)
-                    base._observer.OnCompleted();
-
-                base.Dispose();
+                lock (_gate)
+                    ForwardOnCompleted();
             }
 
             private void Error(Exception exception)
@@ -271,10 +270,8 @@ namespace System.Reactive.Linq.ObservableImpl
                 foreach (var w in _map.Values)
                     w.OnError(exception);
 
-                lock (base._observer)
-                    base._observer.OnError(exception);
-
-                base.Dispose();
+                lock (_gate)
+                    ForwardOnError(exception);
             }
         }
     }

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

@@ -29,7 +29,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
         protected override IDisposable Run(_ sink) => sink.Run(this);
 
-        internal sealed class _ : Sink<TResult>
+        internal sealed class _ : IdentitySink<TResult>
         {
             private readonly object _gate = new object();
             private readonly CompositeDisposable _group = new CompositeDisposable();
@@ -141,7 +141,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
                     lock (_parent._gate)
                     {
-                        _parent._observer.OnNext(result);
+                        _parent.ForwardOnNext(result);
 
                         foreach (var rightValue in _parent._rightMap)
                         {
@@ -193,8 +193,7 @@ namespace System.Reactive.Linq.ObservableImpl
                             o.Value.OnError(error);
                         }
 
-                        _parent._observer.OnError(error);
-                        _parent.Dispose();
+                        _parent.ForwardOnError(error);
                     }
                 }
 
@@ -202,8 +201,7 @@ namespace System.Reactive.Linq.ObservableImpl
                 {
                     lock (_parent._gate)
                     {
-                        _parent._observer.OnCompleted();
-                        _parent.Dispose();
+                        _parent.ForwardOnCompleted();
                     }
 
                     _self.Dispose();
@@ -308,8 +306,7 @@ namespace System.Reactive.Linq.ObservableImpl
                             o.Value.OnError(error);
                         }
 
-                        _parent._observer.OnError(error);
-                        _parent.Dispose();
+                        _parent.ForwardOnError(error);
                     }
                 }
 

+ 2 - 20
Rx.NET/Source/src/System.Reactive/Linq/Observable/If.cs

@@ -25,7 +25,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
         protected override IDisposable Run(_ sink) => sink.Run();
 
-        internal sealed class _ : Sink<TResult>, IObserver<TResult>
+        internal sealed class _ : IdentitySink<TResult>
         {
             private readonly If<TResult> _parent;
 
@@ -44,30 +44,12 @@ namespace System.Reactive.Linq.ObservableImpl
                 }
                 catch (Exception exception)
                 {
-                    base._observer.OnError(exception);
-                    base.Dispose();
+                    ForwardOnError(exception);
                     return Disposable.Empty;
                 }
 
                 return result.SubscribeSafe(this);
             }
-
-            public void OnNext(TResult value)
-            {
-                base._observer.OnNext(value);
-            }
-
-            public void OnError(Exception error)
-            {
-                base._observer.OnError(error);
-                base.Dispose();
-            }
-
-            public void OnCompleted()
-            {
-                base._observer.OnCompleted();
-                base.Dispose();
-            }
         }
     }
 }

+ 2 - 14
Rx.NET/Source/src/System.Reactive/Linq/Observable/IgnoreElements.cs

@@ -17,28 +17,16 @@ namespace System.Reactive.Linq.ObservableImpl
 
         protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-        internal sealed class _ : Sink<TSource>, IObserver<TSource>
+        internal sealed class _ : IdentitySink<TSource>
         {
             public _(IObserver<TSource> observer, IDisposable cancel)
                 : base(observer, cancel)
             {
             }
 
-            public void OnNext(TSource value)
+            public override void OnNext(TSource value)
             {
             }
-
-            public void OnError(Exception error)
-            {
-                base._observer.OnError(error);
-                base.Dispose();
-            }
-
-            public void OnCompleted()
-            {
-                base._observer.OnCompleted();
-                base.Dispose();
-            }
         }
     }
 }

+ 7 - 15
Rx.NET/Source/src/System.Reactive/Linq/Observable/IsEmpty.cs

@@ -17,31 +17,23 @@ namespace System.Reactive.Linq.ObservableImpl
 
         protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-        internal sealed class _ : Sink<bool>, IObserver<TSource>
+        internal sealed class _ : Sink<TSource, bool> 
         {
             public _(IObserver<bool> observer, IDisposable cancel)
                 : base(observer, cancel)
             {
             }
 
-            public void OnNext(TSource value)
+            public override void OnNext(TSource value)
             {
-                base._observer.OnNext(false);
-                base._observer.OnCompleted();
-                base.Dispose();
+                ForwardOnNext(false);
+                ForwardOnCompleted();
             }
 
-            public void OnError(Exception error)
+            public override void OnCompleted()
             {
-                base._observer.OnError(error);
-                base.Dispose();
-            }
-
-            public void OnCompleted()
-            {
-                base._observer.OnNext(true);
-                base._observer.OnCompleted();
-                base.Dispose();
+                ForwardOnNext(true);
+                ForwardOnCompleted();
             }
         }
     }

+ 13 - 23
Rx.NET/Source/src/System.Reactive/Linq/Observable/Join.cs

@@ -28,7 +28,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
         protected override IDisposable Run(_ sink) => sink.Run(this);
 
-        internal sealed class _ : Sink<TResult>
+        internal sealed class _ : IdentitySink<TResult>
         {
             private readonly object _gate = new object();
             private readonly CompositeDisposable _group = new CompositeDisposable();
@@ -88,8 +88,7 @@ namespace System.Reactive.Linq.ObservableImpl
                     {
                         if (_parent._leftMap.Remove(id) && _parent._leftMap.Count == 0 && _parent._leftDone)
                         {
-                            _parent._observer.OnCompleted();
-                            _parent.Dispose();
+                            _parent.ForwardOnCompleted();
                         }
                     }
 
@@ -117,8 +116,7 @@ namespace System.Reactive.Linq.ObservableImpl
                     }
                     catch (Exception exception)
                     {
-                        _parent._observer.OnError(exception);
-                        _parent.Dispose();
+                        _parent.ForwardOnError(exception);
                         return;
                     }
 
@@ -137,12 +135,11 @@ namespace System.Reactive.Linq.ObservableImpl
                                 }
                                 catch (Exception exception)
                                 {
-                                    _parent._observer.OnError(exception);
-                                    _parent.Dispose();
+                                    _parent.ForwardOnError(exception);
                                     return;
                                 }
 
-                                _parent._observer.OnNext(result);
+                                _parent.ForwardOnNext(result);
                             }
                         }
                     }
@@ -181,8 +178,7 @@ namespace System.Reactive.Linq.ObservableImpl
                 {
                     lock (_parent._gate)
                     {
-                        _parent._observer.OnError(error);
-                        _parent.Dispose();
+                        _parent.ForwardOnError(error);
                     }
                 }
 
@@ -193,8 +189,7 @@ namespace System.Reactive.Linq.ObservableImpl
                         _parent._leftDone = true;
                         if (_parent._rightDone || _parent._leftMap.Count == 0)
                         {
-                            _parent._observer.OnCompleted();
-                            _parent.Dispose();
+                            _parent.ForwardOnCompleted();
                         }
                         else
                         {
@@ -221,8 +216,7 @@ namespace System.Reactive.Linq.ObservableImpl
                     {
                         if (_parent._rightMap.Remove(id) && _parent._rightMap.Count == 0 && _parent._rightDone)
                         {
-                            _parent._observer.OnCompleted();
-                            _parent.Dispose();
+                            _parent.ForwardOnCompleted();
                         }
                     }
 
@@ -250,8 +244,7 @@ namespace System.Reactive.Linq.ObservableImpl
                     }
                     catch (Exception exception)
                     {
-                        _parent._observer.OnError(exception);
-                        _parent.Dispose();
+                        _parent.ForwardOnError(exception);
                         return;
                     }
 
@@ -270,12 +263,11 @@ namespace System.Reactive.Linq.ObservableImpl
                                 }
                                 catch (Exception exception)
                                 {
-                                    _parent._observer.OnError(exception);
-                                    _parent.Dispose();
+                                    _parent.ForwardOnError(exception);
                                     return;
                                 }
 
-                                _parent._observer.OnNext(result);
+                                _parent.ForwardOnNext(result);
                             }
                         }
                     }
@@ -314,8 +306,7 @@ namespace System.Reactive.Linq.ObservableImpl
                 {
                     lock (_parent._gate)
                     {
-                        _parent._observer.OnError(error);
-                        _parent.Dispose();
+                        _parent.ForwardOnError(error);
                     }
                 }
 
@@ -326,8 +317,7 @@ namespace System.Reactive.Linq.ObservableImpl
                         _parent._rightDone = true;
                         if (_parent._leftDone || _parent._rightMap.Count == 0)
                         {
-                            _parent._observer.OnCompleted();
-                            _parent.Dispose();
+                            _parent.ForwardOnCompleted();
                         }
                         else
                         {

+ 13 - 30
Rx.NET/Source/src/System.Reactive/Linq/Observable/LastAsync.cs

@@ -19,7 +19,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
             protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-            internal sealed class _ : Sink<TSource>, IObserver<TSource>
+            internal sealed class _ : IdentitySink<TSource>
             {
                 private TSource _value;
                 private bool _seenValue;
@@ -31,31 +31,23 @@ namespace System.Reactive.Linq.ObservableImpl
                     _seenValue = false;
                 }
 
-                public void OnNext(TSource value)
+                public override void OnNext(TSource value)
                 {
                     _value = value;
                     _seenValue = true;
                 }
 
-                public void OnError(Exception error)
-                {
-                    base._observer.OnError(error);
-                    base.Dispose();
-                }
-
-                public void OnCompleted()
+                public override void OnCompleted()
                 {
                     if (!_seenValue)
                     {
-                        base._observer.OnError(new InvalidOperationException(Strings_Linq.NO_ELEMENTS));
+                        ForwardOnError(new InvalidOperationException(Strings_Linq.NO_ELEMENTS));
                     }
                     else
                     {
-                        base._observer.OnNext(_value);
-                        base._observer.OnCompleted();
+                        ForwardOnNext(_value);
+                        ForwardOnCompleted();
                     }
-
-                    base.Dispose();
                 }
             }
         }
@@ -75,7 +67,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
             protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-            internal sealed class _ : Sink<TSource>, IObserver<TSource>
+            internal sealed class _ : IdentitySink<TSource>
             {
                 private readonly Func<TSource, bool> _predicate;
                 private TSource _value;
@@ -90,7 +82,7 @@ namespace System.Reactive.Linq.ObservableImpl
                     _seenValue = false;
                 }
 
-                public void OnNext(TSource value)
+                public override void OnNext(TSource value)
                 {
                     var b = false;
 
@@ -100,8 +92,7 @@ namespace System.Reactive.Linq.ObservableImpl
                     }
                     catch (Exception ex)
                     {
-                        base._observer.OnError(ex);
-                        base.Dispose();
+                        ForwardOnError(ex);
                         return;
                     }
 
@@ -112,25 +103,17 @@ namespace System.Reactive.Linq.ObservableImpl
                     }
                 }
 
-                public void OnError(Exception error)
-                {
-                    base._observer.OnError(error);
-                    base.Dispose();
-                }
-
-                public void OnCompleted()
+                public override void OnCompleted()
                 {
                     if (!_seenValue)
                     {
-                        base._observer.OnError(new InvalidOperationException(Strings_Linq.NO_MATCHING_ELEMENTS));
+                        ForwardOnError(new InvalidOperationException(Strings_Linq.NO_MATCHING_ELEMENTS));
                     }
                     else
                     {
-                        base._observer.OnNext(_value);
-                        base._observer.OnCompleted();
+                        ForwardOnNext(_value);
+                        ForwardOnCompleted();
                     }
-
-                    base.Dispose();
                 }
             }
         }

+ 11 - 26
Rx.NET/Source/src/System.Reactive/Linq/Observable/LastOrDefaultAsync.cs

@@ -19,7 +19,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
             protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-            internal sealed class _ : Sink<TSource>, IObserver<TSource>
+            internal sealed class _ : IdentitySink<TSource>
             {
                 private TSource _value;
 
@@ -29,22 +29,15 @@ namespace System.Reactive.Linq.ObservableImpl
                     _value = default(TSource);
                 }
 
-                public void OnNext(TSource value)
+                public override void OnNext(TSource value)
                 {
                     _value = value;
                 }
 
-                public void OnError(Exception error)
+                public override void OnCompleted()
                 {
-                    base._observer.OnError(error);
-                    base.Dispose();
-                }
-
-                public void OnCompleted()
-                {
-                    base._observer.OnNext(_value);
-                    base._observer.OnCompleted();
-                    base.Dispose();
+                    ForwardOnNext(_value);
+                    ForwardOnCompleted();
                 }
             }
         }
@@ -64,7 +57,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
             protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-            internal sealed class _ : Sink<TSource>, IObserver<TSource>
+            internal sealed class _ : IdentitySink<TSource>
             {
                 private readonly Func<TSource, bool> _predicate;
                 private TSource _value;
@@ -77,7 +70,7 @@ namespace System.Reactive.Linq.ObservableImpl
                     _value = default(TSource);
                 }
 
-                public void OnNext(TSource value)
+                public override void OnNext(TSource value)
                 {
                     var b = false;
 
@@ -87,8 +80,7 @@ namespace System.Reactive.Linq.ObservableImpl
                     }
                     catch (Exception ex)
                     {
-                        base._observer.OnError(ex);
-                        base.Dispose();
+                        ForwardOnError(ex);
                         return;
                     }
 
@@ -98,17 +90,10 @@ namespace System.Reactive.Linq.ObservableImpl
                     }
                 }
 
-                public void OnError(Exception error)
-                {
-                    base._observer.OnError(error);
-                    base.Dispose();
-                }
-
-                public void OnCompleted()
+                public override void OnCompleted()
                 {
-                    base._observer.OnNext(_value);
-                    base._observer.OnCompleted();
-                    base.Dispose();
+                    ForwardOnNext(_value);
+                    ForwardOnCompleted();
                 }
             }
         }

+ 12 - 28
Rx.NET/Source/src/System.Reactive/Linq/Observable/LongCount.cs

@@ -19,7 +19,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
             protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-            internal sealed class _ : Sink<long>, IObserver<TSource>
+            internal sealed class _ : Sink<TSource, long> 
             {
                 private long _count;
 
@@ -29,7 +29,7 @@ namespace System.Reactive.Linq.ObservableImpl
                     _count = 0L;
                 }
 
-                public void OnNext(TSource value)
+                public override void OnNext(TSource value)
                 {
                     try
                     {
@@ -40,22 +40,14 @@ namespace System.Reactive.Linq.ObservableImpl
                     }
                     catch (Exception ex)
                     {
-                        base._observer.OnError(ex);
-                        base.Dispose();
+                        ForwardOnError(ex);
                     }
                 }
 
-                public void OnError(Exception error)
+                public override void OnCompleted()
                 {
-                    base._observer.OnError(error);
-                    base.Dispose();
-                }
-
-                public void OnCompleted()
-                {
-                    base._observer.OnNext(_count);
-                    base._observer.OnCompleted();
-                    base.Dispose();
+                    ForwardOnNext(_count);
+                    ForwardOnCompleted();
                 }
             }
         }
@@ -75,7 +67,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
             protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-            internal sealed class _ : Sink<long>, IObserver<TSource>
+            internal sealed class _ : Sink<TSource, long> 
             {
                 private readonly Func<TSource, bool> _predicate;
                 private long _count;
@@ -87,7 +79,7 @@ namespace System.Reactive.Linq.ObservableImpl
                     _count = 0L;
                 }
 
-                public void OnNext(TSource value)
+                public override void OnNext(TSource value)
                 {
                     try
                     {
@@ -101,22 +93,14 @@ namespace System.Reactive.Linq.ObservableImpl
                     }
                     catch (Exception ex)
                     {
-                        base._observer.OnError(ex);
-                        base.Dispose();
+                        ForwardOnError(ex);
                     }
                 }
 
-                public void OnError(Exception error)
-                {
-                    base._observer.OnError(error);
-                    base.Dispose();
-                }
-
-                public void OnCompleted()
+                public override void OnCompleted()
                 {
-                    base._observer.OnNext(_count);
-                    base._observer.OnCompleted();
-                    base.Dispose();
+                    ForwardOnNext(_count);
+                    ForwardOnCompleted();
                 }
             }
         }

+ 9 - 11
Rx.NET/Source/src/System.Reactive/Linq/Observable/Materialize.cs

@@ -19,30 +19,28 @@ namespace System.Reactive.Linq.ObservableImpl
 
         protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-        internal sealed class _ : Sink<Notification<TSource>>, IObserver<TSource>
+        internal sealed class _ : Sink<TSource, Notification<TSource>> 
         {
             public _(IObserver<Notification<TSource>> observer, IDisposable cancel)
                 : base(observer, cancel)
             {
             }
 
-            public void OnNext(TSource value)
+            public override void OnNext(TSource value)
             {
-                base._observer.OnNext(Notification.CreateOnNext<TSource>(value));
+                ForwardOnNext(Notification.CreateOnNext<TSource>(value));
             }
 
-            public void OnError(Exception error)
+            public override void OnError(Exception error)
             {
-                base._observer.OnNext(Notification.CreateOnError<TSource>(error));
-                base._observer.OnCompleted();
-                base.Dispose();
+                ForwardOnNext(Notification.CreateOnError<TSource>(error));
+                ForwardOnCompleted();
             }
 
-            public void OnCompleted()
+            public override void OnCompleted()
             {
-                base._observer.OnNext(Notification.CreateOnCompleted<TSource>());
-                base._observer.OnCompleted();
-                base.Dispose();
+                ForwardOnNext(Notification.CreateOnCompleted<TSource>());
+                ForwardOnCompleted();
             }
         }
     }

+ 64 - 155
Rx.NET/Source/src/System.Reactive/Linq/Observable/Max.cs

@@ -21,7 +21,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
         protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-        internal abstract class _ : Sink<TSource>, IObserver<TSource>
+        internal abstract class _ : IdentitySink<TSource>
         {
             protected readonly IComparer<TSource> _comparer;
 
@@ -30,10 +30,6 @@ namespace System.Reactive.Linq.ObservableImpl
             {
                 _comparer = comparer;
             }
-
-            public abstract void OnCompleted();
-            public abstract void OnError(Exception error);
-            public abstract void OnNext(TSource value);
         }
 
         private sealed class NonNull : _
@@ -60,8 +56,7 @@ namespace System.Reactive.Linq.ObservableImpl
                     }
                     catch (Exception ex)
                     {
-                        base._observer.OnError(ex);
-                        base.Dispose();
+                        ForwardOnError(ex);
                         return;
                     }
 
@@ -77,25 +72,17 @@ namespace System.Reactive.Linq.ObservableImpl
                 }
             }
 
-            public override void OnError(Exception error)
-            {
-                base._observer.OnError(error);
-                base.Dispose();
-            }
-
             public override void OnCompleted()
             {
                 if (!_hasValue)
                 {
-                    base._observer.OnError(new InvalidOperationException(Strings_Linq.NO_ELEMENTS));
+                    ForwardOnError(new InvalidOperationException(Strings_Linq.NO_ELEMENTS));
                 }
                 else
                 {
-                    base._observer.OnNext(_lastValue);
-                    base._observer.OnCompleted();
+                    ForwardOnNext(_lastValue);
+                    ForwardOnCompleted();
                 }
-
-                base.Dispose();
             }
         }
 
@@ -127,8 +114,7 @@ namespace System.Reactive.Linq.ObservableImpl
                         }
                         catch (Exception ex)
                         {
-                            base._observer.OnError(ex);
-                            base.Dispose();
+                            ForwardOnError(ex);
                             return;
                         }
 
@@ -142,15 +128,13 @@ namespace System.Reactive.Linq.ObservableImpl
 
             public override void OnError(Exception error)
             {
-                base._observer.OnError(error);
-                base.Dispose();
+                ForwardOnError(error);
             }
 
             public override void OnCompleted()
             {
-                base._observer.OnNext(_lastValue);
-                base._observer.OnCompleted();
-                base.Dispose();
+                ForwardOnNext(_lastValue);
+                ForwardOnCompleted();
             }
         }
     }
@@ -168,7 +152,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
         protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-        internal sealed class _ : Sink<double>, IObserver<double>
+        internal sealed class _ : IdentitySink<double>
         {
             private bool _hasValue;
             private double _lastValue;
@@ -180,7 +164,7 @@ namespace System.Reactive.Linq.ObservableImpl
                 _lastValue = default(double);
             }
 
-            public void OnNext(double value)
+            public override void OnNext(double value)
             {
                 if (_hasValue)
                 {
@@ -196,25 +180,17 @@ namespace System.Reactive.Linq.ObservableImpl
                 }
             }
 
-            public void OnError(Exception error)
-            {
-                base._observer.OnError(error);
-                base.Dispose();
-            }
-
-            public void OnCompleted()
+            public override void OnCompleted()
             {
                 if (!_hasValue)
                 {
-                    base._observer.OnError(new InvalidOperationException(Strings_Linq.NO_ELEMENTS));
+                    ForwardOnError(new InvalidOperationException(Strings_Linq.NO_ELEMENTS));
                 }
                 else
                 {
-                    base._observer.OnNext(_lastValue);
-                    base._observer.OnCompleted();
+                    ForwardOnNext(_lastValue);
+                    ForwardOnCompleted();
                 }
-
-                base.Dispose();
             }
         }
     }
@@ -232,7 +208,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
         protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-        internal sealed class _ : Sink<float>, IObserver<float>
+        internal sealed class _ : IdentitySink<float>
         {
             private bool _hasValue;
             private float _lastValue;
@@ -244,7 +220,7 @@ namespace System.Reactive.Linq.ObservableImpl
                 _lastValue = default(float);
             }
 
-            public void OnNext(float value)
+            public override void OnNext(float value)
             {
                 if (_hasValue)
                 {
@@ -260,25 +236,17 @@ namespace System.Reactive.Linq.ObservableImpl
                 }
             }
 
-            public void OnError(Exception error)
-            {
-                base._observer.OnError(error);
-                base.Dispose();
-            }
-
-            public void OnCompleted()
+            public override void OnCompleted()
             {
                 if (!_hasValue)
                 {
-                    base._observer.OnError(new InvalidOperationException(Strings_Linq.NO_ELEMENTS));
+                    ForwardOnError(new InvalidOperationException(Strings_Linq.NO_ELEMENTS));
                 }
                 else
                 {
-                    base._observer.OnNext(_lastValue);
-                    base._observer.OnCompleted();
+                    ForwardOnNext(_lastValue);
+                    ForwardOnCompleted();
                 }
-
-                base.Dispose();
             }
         }
     }
@@ -296,7 +264,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
         protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-        internal sealed class _ : Sink<decimal>, IObserver<decimal>
+        internal sealed class _ : IdentitySink<decimal>
         {
             private bool _hasValue;
             private decimal _lastValue;
@@ -308,7 +276,7 @@ namespace System.Reactive.Linq.ObservableImpl
                 _lastValue = default(decimal);
             }
 
-            public void OnNext(decimal value)
+            public override void OnNext(decimal value)
             {
                 if (_hasValue)
                 {
@@ -324,25 +292,17 @@ namespace System.Reactive.Linq.ObservableImpl
                 }
             }
 
-            public void OnError(Exception error)
-            {
-                base._observer.OnError(error);
-                base.Dispose();
-            }
-
-            public void OnCompleted()
+            public override void OnCompleted()
             {
                 if (!_hasValue)
                 {
-                    base._observer.OnError(new InvalidOperationException(Strings_Linq.NO_ELEMENTS));
+                    ForwardOnError(new InvalidOperationException(Strings_Linq.NO_ELEMENTS));
                 }
                 else
                 {
-                    base._observer.OnNext(_lastValue);
-                    base._observer.OnCompleted();
+                    ForwardOnNext(_lastValue);
+                    ForwardOnCompleted();
                 }
-
-                base.Dispose();
             }
         }
     }
@@ -360,7 +320,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
         protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-        internal sealed class _ : Sink<int>, IObserver<int>
+        internal sealed class _ : IdentitySink<int>
         {
             private bool _hasValue;
             private int _lastValue;
@@ -372,7 +332,7 @@ namespace System.Reactive.Linq.ObservableImpl
                 _lastValue = default(int);
             }
 
-            public void OnNext(int value)
+            public override void OnNext(int value)
             {
                 if (_hasValue)
                 {
@@ -388,25 +348,17 @@ namespace System.Reactive.Linq.ObservableImpl
                 }
             }
 
-            public void OnError(Exception error)
-            {
-                base._observer.OnError(error);
-                base.Dispose();
-            }
-
-            public void OnCompleted()
+            public override void OnCompleted()
             {
                 if (!_hasValue)
                 {
-                    base._observer.OnError(new InvalidOperationException(Strings_Linq.NO_ELEMENTS));
+                    ForwardOnError(new InvalidOperationException(Strings_Linq.NO_ELEMENTS));
                 }
                 else
                 {
-                    base._observer.OnNext(_lastValue);
-                    base._observer.OnCompleted();
+                    ForwardOnNext(_lastValue);
+                    ForwardOnCompleted();
                 }
-
-                base.Dispose();
             }
         }
     }
@@ -424,7 +376,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
         protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-        internal sealed class _ : Sink<long>, IObserver<long>
+        internal sealed class _ : IdentitySink<long>
         {
             private bool _hasValue;
             private long _lastValue;
@@ -436,7 +388,7 @@ namespace System.Reactive.Linq.ObservableImpl
                 _lastValue = default(long);
             }
 
-            public void OnNext(long value)
+            public override void OnNext(long value)
             {
                 if (_hasValue)
                 {
@@ -452,25 +404,17 @@ namespace System.Reactive.Linq.ObservableImpl
                 }
             }
 
-            public void OnError(Exception error)
-            {
-                base._observer.OnError(error);
-                base.Dispose();
-            }
-
-            public void OnCompleted()
+            public override void OnCompleted()
             {
                 if (!_hasValue)
                 {
-                    base._observer.OnError(new InvalidOperationException(Strings_Linq.NO_ELEMENTS));
+                    ForwardOnError(new InvalidOperationException(Strings_Linq.NO_ELEMENTS));
                 }
                 else
                 {
-                    base._observer.OnNext(_lastValue);
-                    base._observer.OnCompleted();
+                    ForwardOnNext(_lastValue);
+                    ForwardOnCompleted();
                 }
-
-                base.Dispose();
             }
         }
     }
@@ -488,7 +432,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
         protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-        internal sealed class _ : Sink<double?>, IObserver<double?>
+        internal sealed class _ : IdentitySink<double?>
         {
             private double? _lastValue;
 
@@ -498,7 +442,7 @@ namespace System.Reactive.Linq.ObservableImpl
                 _lastValue = default(double?);
             }
 
-            public void OnNext(double? value)
+            public override void OnNext(double? value)
             {
                 if (!value.HasValue)
                     return;
@@ -516,17 +460,10 @@ namespace System.Reactive.Linq.ObservableImpl
                 }
             }
 
-            public void OnError(Exception error)
-            {
-                base._observer.OnError(error);
-                base.Dispose();
-            }
-
-            public void OnCompleted()
+            public override void OnCompleted()
             {
-                base._observer.OnNext(_lastValue);
-                base._observer.OnCompleted();
-                base.Dispose();
+                ForwardOnNext(_lastValue);
+                ForwardOnCompleted();
             }
         }
     }
@@ -544,7 +481,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
         protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-        internal sealed class _ : Sink<float?>, IObserver<float?>
+        internal sealed class _ : IdentitySink<float?>
         {
             private float? _lastValue;
 
@@ -554,7 +491,7 @@ namespace System.Reactive.Linq.ObservableImpl
                 _lastValue = default(float?);
             }
 
-            public void OnNext(float? value)
+            public override void OnNext(float? value)
             {
                 if (!value.HasValue)
                     return;
@@ -572,17 +509,10 @@ namespace System.Reactive.Linq.ObservableImpl
                 }
             }
 
-            public void OnError(Exception error)
-            {
-                base._observer.OnError(error);
-                base.Dispose();
-            }
-
-            public void OnCompleted()
+            public override void OnCompleted()
             {
-                base._observer.OnNext(_lastValue);
-                base._observer.OnCompleted();
-                base.Dispose();
+                ForwardOnNext(_lastValue);
+                ForwardOnCompleted();
             }
         }
     }
@@ -600,7 +530,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
         protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-        internal sealed class _ : Sink<decimal?>, IObserver<decimal?>
+        internal sealed class _ : IdentitySink<decimal?>
         {
             private decimal? _lastValue;
 
@@ -610,7 +540,7 @@ namespace System.Reactive.Linq.ObservableImpl
                 _lastValue = default(decimal?);
             }
 
-            public void OnNext(decimal? value)
+            public override void OnNext(decimal? value)
             {
                 if (!value.HasValue)
                     return;
@@ -628,17 +558,10 @@ namespace System.Reactive.Linq.ObservableImpl
                 }
             }
 
-            public void OnError(Exception error)
-            {
-                base._observer.OnError(error);
-                base.Dispose();
-            }
-
-            public void OnCompleted()
+            public override void OnCompleted()
             {
-                base._observer.OnNext(_lastValue);
-                base._observer.OnCompleted();
-                base.Dispose();
+                ForwardOnNext(_lastValue);
+                ForwardOnCompleted();
             }
         }
     }
@@ -656,7 +579,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
         protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-        internal sealed class _ : Sink<int?>, IObserver<int?>
+        internal sealed class _ : IdentitySink<int?>
         {
             private int? _lastValue;
 
@@ -666,7 +589,7 @@ namespace System.Reactive.Linq.ObservableImpl
                 _lastValue = default(int?);
             }
 
-            public void OnNext(int? value)
+            public override void OnNext(int? value)
             {
                 if (!value.HasValue)
                     return;
@@ -684,17 +607,10 @@ namespace System.Reactive.Linq.ObservableImpl
                 }
             }
 
-            public void OnError(Exception error)
-            {
-                base._observer.OnError(error);
-                base.Dispose();
-            }
-
-            public void OnCompleted()
+            public override void OnCompleted()
             {
-                base._observer.OnNext(_lastValue);
-                base._observer.OnCompleted();
-                base.Dispose();
+                ForwardOnNext(_lastValue);
+                ForwardOnCompleted();
             }
         }
     }
@@ -712,7 +628,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
         protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-        internal sealed class _ : Sink<long?>, IObserver<long?>
+        internal sealed class _ : IdentitySink<long?>
         {
             private long? _lastValue;
 
@@ -722,7 +638,7 @@ namespace System.Reactive.Linq.ObservableImpl
                 _lastValue = default(long?);
             }
 
-            public void OnNext(long? value)
+            public override void OnNext(long? value)
             {
                 if (!value.HasValue)
                     return;
@@ -740,17 +656,10 @@ namespace System.Reactive.Linq.ObservableImpl
                 }
             }
 
-            public void OnError(Exception error)
-            {
-                base._observer.OnError(error);
-                base.Dispose();
-            }
-
-            public void OnCompleted()
+            public override void OnCompleted()
             {
-                base._observer.OnNext(_lastValue);
-                base._observer.OnCompleted();
-                base.Dispose();
+                ForwardOnNext(_lastValue);
+                ForwardOnCompleted();
             }
         }
     }

+ 7 - 16
Rx.NET/Source/src/System.Reactive/Linq/Observable/MaxBy.cs

@@ -23,7 +23,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
         protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-        internal sealed class _ : Sink<IList<TSource>>, IObserver<TSource>
+        internal sealed class _ : Sink<TSource, IList<TSource>> 
         {
             private readonly MaxBy<TSource, TKey> _parent;
             private bool _hasValue;
@@ -40,7 +40,7 @@ namespace System.Reactive.Linq.ObservableImpl
                 _list = new List<TSource>();
             }
 
-            public void OnNext(TSource value)
+            public override void OnNext(TSource value)
             {
                 var key = default(TKey);
                 try
@@ -49,8 +49,7 @@ namespace System.Reactive.Linq.ObservableImpl
                 }
                 catch (Exception ex)
                 {
-                    base._observer.OnError(ex);
-                    base.Dispose();
+                    ForwardOnError(ex);
                     return;
                 }
 
@@ -69,8 +68,7 @@ namespace System.Reactive.Linq.ObservableImpl
                     }
                     catch (Exception ex)
                     {
-                        base._observer.OnError(ex);
-                        base.Dispose();
+                        ForwardOnError(ex);
                         return;
                     }
                 }
@@ -87,17 +85,10 @@ namespace System.Reactive.Linq.ObservableImpl
                 }
             }
 
-            public void OnError(Exception error)
+            public override void OnCompleted()
             {
-                base._observer.OnError(error);
-                base.Dispose();
-            }
-
-            public void OnCompleted()
-            {
-                base._observer.OnNext(_list);
-                base._observer.OnCompleted();
-                base.Dispose();
+                ForwardOnNext(_list);
+                ForwardOnCompleted();
             }
         }
     }

+ 27 - 39
Rx.NET/Source/src/System.Reactive/Linq/Observable/Merge.cs

@@ -26,7 +26,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
             protected override IDisposable Run(_ sink) => sink.Run(this);
 
-            internal sealed class _ : Sink<TSource>, IObserver<IObservable<TSource>>
+            internal sealed class _ : Sink<IObservable<TSource>, TSource> 
             {
                 private readonly int _maxConcurrent;
 
@@ -58,7 +58,7 @@ namespace System.Reactive.Linq.ObservableImpl
                     return _group;
                 }
 
-                public void OnNext(IObservable<TSource> value)
+                public override void OnNext(IObservable<TSource> value)
                 {
                     lock (_gate)
                     {
@@ -72,24 +72,22 @@ namespace System.Reactive.Linq.ObservableImpl
                     }
                 }
 
-                public void OnError(Exception error)
+                public override void OnError(Exception error)
                 {
                     lock (_gate)
                     {
-                        base._observer.OnError(error);
-                        base.Dispose();
+                        ForwardOnError(error);
                     }
                 }
 
-                public void OnCompleted()
+                public override void OnCompleted()
                 {
                     lock (_gate)
                     {
                         _isStopped = true;
                         if (_activeCount == 0)
                         {
-                            base._observer.OnCompleted();
-                            base.Dispose();
+                            ForwardOnCompleted();
                         }
                         else
                         {
@@ -119,15 +117,14 @@ namespace System.Reactive.Linq.ObservableImpl
                     public void OnNext(TSource value)
                     {
                         lock (_parent._gate)
-                            _parent._observer.OnNext(value);
+                            _parent.ForwardOnNext(value);
                     }
 
                     public void OnError(Exception error)
                     {
                         lock (_parent._gate)
                         {
-                            _parent._observer.OnError(error);
-                            _parent.Dispose();
+                            _parent.ForwardOnError(error);
                         }
                     }
 
@@ -146,8 +143,7 @@ namespace System.Reactive.Linq.ObservableImpl
                                 _parent._activeCount--;
                                 if (_parent._isStopped && _parent._activeCount == 0)
                                 {
-                                    _parent._observer.OnCompleted();
-                                    _parent.Dispose();
+                                    _parent.ForwardOnCompleted();
                                 }
                             }
                         }
@@ -169,7 +165,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
             protected override IDisposable Run(_ sink) => sink.Run(this);
 
-            internal sealed class _ : Sink<TSource>, IObserver<IObservable<TSource>>
+            internal sealed class _ : Sink<IObservable<TSource>, TSource> 
             {
                 public _(IObserver<TSource> observer, IDisposable cancel)
                     : base(observer, cancel)
@@ -194,23 +190,22 @@ namespace System.Reactive.Linq.ObservableImpl
                     return _group;
                 }
 
-                public void OnNext(IObservable<TSource> value)
+                public override void OnNext(IObservable<TSource> value)
                 {
                     var innerSubscription = new SingleAssignmentDisposable();
                     _group.Add(innerSubscription);
                     innerSubscription.Disposable = value.SubscribeSafe(new InnerObserver(this, innerSubscription));
                 }
 
-                public void OnError(Exception error)
+                public override void OnError(Exception error)
                 {
                     lock (_gate)
                     {
-                        base._observer.OnError(error);
-                        base.Dispose();
+                        ForwardOnError(error);
                     }
                 }
 
-                public void OnCompleted()
+                public override void OnCompleted()
                 {
                     _isStopped = true;
                     if (_group.Count == 1)
@@ -224,8 +219,7 @@ namespace System.Reactive.Linq.ObservableImpl
                         //
                         lock (_gate)
                         {
-                            base._observer.OnCompleted();
-                            base.Dispose();
+                            ForwardOnCompleted();
                         }
                     }
                     else
@@ -248,15 +242,14 @@ namespace System.Reactive.Linq.ObservableImpl
                     public void OnNext(TSource value)
                     {
                         lock (_parent._gate)
-                            _parent._observer.OnNext(value);
+                            _parent.ForwardOnNext(value);
                     }
 
                     public void OnError(Exception error)
                     {
                         lock (_parent._gate)
                         {
-                            _parent._observer.OnError(error);
-                            _parent.Dispose();
+                            _parent.ForwardOnError(error);
                         }
                     }
 
@@ -274,8 +267,7 @@ namespace System.Reactive.Linq.ObservableImpl
                             //
                             lock (_parent._gate)
                             {
-                                _parent._observer.OnCompleted();
-                                _parent.Dispose();
+                                _parent.ForwardOnCompleted();
                             }
                         }
                     }
@@ -296,7 +288,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
             protected override IDisposable Run(_ sink) => sink.Run(this);
 
-            internal sealed class _ : Sink<TSource>, IObserver<Task<TSource>>
+            internal sealed class _ : Sink<Task<TSource>, TSource> 
             {
                 public _(IObserver<TSource> observer, IDisposable cancel)
                     : base(observer, cancel)
@@ -314,7 +306,7 @@ namespace System.Reactive.Linq.ObservableImpl
                     return parent._sources.SubscribeSafe(this);
                 }
 
-                public void OnNext(Task<TSource> value)
+                public override void OnNext(Task<TSource> value)
                 {
                     Interlocked.Increment(ref _count);
                     if (value.IsCompleted)
@@ -334,7 +326,7 @@ namespace System.Reactive.Linq.ObservableImpl
                         case TaskStatus.RanToCompletion:
                             {
                                 lock (_gate)
-                                    base._observer.OnNext(task.Result);
+                                    ForwardOnNext(task.Result);
 
                                 OnCompleted();
                             }
@@ -343,8 +335,7 @@ namespace System.Reactive.Linq.ObservableImpl
                             {
                                 lock (_gate)
                                 {
-                                    base._observer.OnError(task.Exception.InnerException);
-                                    base.Dispose();
+                                    ForwardOnError(task.Exception.InnerException);
                                 }
                             }
                             break;
@@ -352,31 +343,28 @@ namespace System.Reactive.Linq.ObservableImpl
                             {
                                 lock (_gate)
                                 {
-                                    base._observer.OnError(new TaskCanceledException(task));
-                                    base.Dispose();
+                                    ForwardOnError(new TaskCanceledException(task));
                                 }
                             }
                             break;
                     }
                 }
 
-                public void OnError(Exception error)
+                public override void OnError(Exception error)
                 {
                     lock (_gate)
                     {
-                        base._observer.OnError(error);
-                        base.Dispose();
+                        ForwardOnError(error);
                     }
                 }
 
-                public void OnCompleted()
+                public override void OnCompleted()
                 {
                     if (Interlocked.Decrement(ref _count) == 0)
                     {
                         lock (_gate)
                         {
-                            base._observer.OnCompleted();
-                            base.Dispose();
+                            ForwardOnCompleted();
                         }
                     }
                 }

+ 64 - 155
Rx.NET/Source/src/System.Reactive/Linq/Observable/Min.cs

@@ -21,7 +21,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
         protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-        internal abstract class _ : Sink<TSource>, IObserver<TSource>
+        internal abstract class _ : IdentitySink<TSource>
         {
             protected readonly IComparer<TSource> _comparer;
 
@@ -30,10 +30,6 @@ namespace System.Reactive.Linq.ObservableImpl
             {
                 _comparer = comparer;
             }
-
-            public abstract void OnCompleted();
-            public abstract void OnError(Exception error);
-            public abstract void OnNext(TSource value);
         }
 
         private sealed class NonNull : _
@@ -60,8 +56,7 @@ namespace System.Reactive.Linq.ObservableImpl
                     }
                     catch (Exception ex)
                     {
-                        base._observer.OnError(ex);
-                        base.Dispose();
+                        ForwardOnError(ex);
                         return;
                     }
 
@@ -79,23 +74,20 @@ namespace System.Reactive.Linq.ObservableImpl
 
             public override void OnError(Exception error)
             {
-                base._observer.OnError(error);
-                base.Dispose();
+                ForwardOnError(error);
             }
 
             public override void OnCompleted()
             {
                 if (!_hasValue)
                 {
-                    base._observer.OnError(new InvalidOperationException(Strings_Linq.NO_ELEMENTS));
+                    ForwardOnError(new InvalidOperationException(Strings_Linq.NO_ELEMENTS));
                 }
                 else
                 {
-                    base._observer.OnNext(_lastValue);
-                    base._observer.OnCompleted();
+                    ForwardOnNext(_lastValue);
+                    ForwardOnCompleted();
                 }
-
-                base.Dispose();
             }
         }
 
@@ -127,8 +119,7 @@ namespace System.Reactive.Linq.ObservableImpl
                         }
                         catch (Exception ex)
                         {
-                            base._observer.OnError(ex);
-                            base.Dispose();
+                            ForwardOnError(ex);
                             return;
                         }
 
@@ -140,17 +131,10 @@ namespace System.Reactive.Linq.ObservableImpl
                 }
             }
 
-            public override void OnError(Exception error)
-            {
-                base._observer.OnError(error);
-                base.Dispose();
-            }
-
             public override void OnCompleted()
             {
-                base._observer.OnNext(_lastValue);
-                base._observer.OnCompleted();
-                base.Dispose();
+                ForwardOnNext(_lastValue);
+                ForwardOnCompleted();
             }
         }
     }
@@ -168,7 +152,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
         protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-        internal sealed class _ : Sink<double>, IObserver<double>
+        internal sealed class _ : IdentitySink<double>
         {
             private bool _hasValue;
             private double _lastValue;
@@ -180,7 +164,7 @@ namespace System.Reactive.Linq.ObservableImpl
                 _lastValue = default(double);
             }
 
-            public void OnNext(double value)
+            public override void OnNext(double value)
             {
                 if (_hasValue)
                 {
@@ -196,25 +180,17 @@ namespace System.Reactive.Linq.ObservableImpl
                 }
             }
 
-            public void OnError(Exception error)
-            {
-                base._observer.OnError(error);
-                base.Dispose();
-            }
-
-            public void OnCompleted()
+            public override void OnCompleted()
             {
                 if (!_hasValue)
                 {
-                    base._observer.OnError(new InvalidOperationException(Strings_Linq.NO_ELEMENTS));
+                    ForwardOnError(new InvalidOperationException(Strings_Linq.NO_ELEMENTS));
                 }
                 else
                 {
-                    base._observer.OnNext(_lastValue);
-                    base._observer.OnCompleted();
+                    ForwardOnNext(_lastValue);
+                    ForwardOnCompleted();
                 }
-
-                base.Dispose();
             }
         }
     }
@@ -232,7 +208,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
         protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-        internal sealed class _ : Sink<float>, IObserver<float>
+        internal sealed class _ : IdentitySink<float>
         {
             private bool _hasValue;
             private float _lastValue;
@@ -244,7 +220,7 @@ namespace System.Reactive.Linq.ObservableImpl
                 _lastValue = default(float);
             }
 
-            public void OnNext(float value)
+            public override void OnNext(float value)
             {
                 if (_hasValue)
                 {
@@ -260,25 +236,17 @@ namespace System.Reactive.Linq.ObservableImpl
                 }
             }
 
-            public void OnError(Exception error)
-            {
-                base._observer.OnError(error);
-                base.Dispose();
-            }
-
-            public void OnCompleted()
+            public override void OnCompleted()
             {
                 if (!_hasValue)
                 {
-                    base._observer.OnError(new InvalidOperationException(Strings_Linq.NO_ELEMENTS));
+                    ForwardOnError(new InvalidOperationException(Strings_Linq.NO_ELEMENTS));
                 }
                 else
                 {
-                    base._observer.OnNext(_lastValue);
-                    base._observer.OnCompleted();
+                    ForwardOnNext(_lastValue);
+                    ForwardOnCompleted();
                 }
-
-                base.Dispose();
             }
         }
     }
@@ -296,7 +264,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
         protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-        internal sealed class _ : Sink<decimal>, IObserver<decimal>
+        internal sealed class _ : IdentitySink<decimal>
         {
             private bool _hasValue;
             private decimal _lastValue;
@@ -308,7 +276,7 @@ namespace System.Reactive.Linq.ObservableImpl
                 _lastValue = default(decimal);
             }
 
-            public void OnNext(decimal value)
+            public override void OnNext(decimal value)
             {
                 if (_hasValue)
                 {
@@ -324,25 +292,17 @@ namespace System.Reactive.Linq.ObservableImpl
                 }
             }
 
-            public void OnError(Exception error)
-            {
-                base._observer.OnError(error);
-                base.Dispose();
-            }
-
-            public void OnCompleted()
+            public override void OnCompleted()
             {
                 if (!_hasValue)
                 {
-                    base._observer.OnError(new InvalidOperationException(Strings_Linq.NO_ELEMENTS));
+                    ForwardOnError(new InvalidOperationException(Strings_Linq.NO_ELEMENTS));
                 }
                 else
                 {
-                    base._observer.OnNext(_lastValue);
-                    base._observer.OnCompleted();
+                    ForwardOnNext(_lastValue);
+                    ForwardOnCompleted();
                 }
-
-                base.Dispose();
             }
         }
     }
@@ -360,7 +320,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
         protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-        internal sealed class _ : Sink<int>, IObserver<int>
+        internal sealed class _ : IdentitySink<int>
         {
             private bool _hasValue;
             private int _lastValue;
@@ -372,7 +332,7 @@ namespace System.Reactive.Linq.ObservableImpl
                 _lastValue = default(int);
             }
 
-            public void OnNext(int value)
+            public override void OnNext(int value)
             {
                 if (_hasValue)
                 {
@@ -388,25 +348,17 @@ namespace System.Reactive.Linq.ObservableImpl
                 }
             }
 
-            public void OnError(Exception error)
-            {
-                base._observer.OnError(error);
-                base.Dispose();
-            }
-
-            public void OnCompleted()
+            public override void OnCompleted()
             {
                 if (!_hasValue)
                 {
-                    base._observer.OnError(new InvalidOperationException(Strings_Linq.NO_ELEMENTS));
+                    ForwardOnError(new InvalidOperationException(Strings_Linq.NO_ELEMENTS));
                 }
                 else
                 {
-                    base._observer.OnNext(_lastValue);
-                    base._observer.OnCompleted();
+                    ForwardOnNext(_lastValue);
+                    ForwardOnCompleted();
                 }
-
-                base.Dispose();
             }
         }
     }
@@ -424,7 +376,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
         protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-        internal sealed class _ : Sink<long>, IObserver<long>
+        internal sealed class _ : IdentitySink<long>
         {
             private bool _hasValue;
             private long _lastValue;
@@ -436,7 +388,7 @@ namespace System.Reactive.Linq.ObservableImpl
                 _lastValue = default(long);
             }
 
-            public void OnNext(long value)
+            public override void OnNext(long value)
             {
                 if (_hasValue)
                 {
@@ -452,25 +404,17 @@ namespace System.Reactive.Linq.ObservableImpl
                 }
             }
 
-            public void OnError(Exception error)
-            {
-                base._observer.OnError(error);
-                base.Dispose();
-            }
-
-            public void OnCompleted()
+            public override void OnCompleted()
             {
                 if (!_hasValue)
                 {
-                    base._observer.OnError(new InvalidOperationException(Strings_Linq.NO_ELEMENTS));
+                    ForwardOnError(new InvalidOperationException(Strings_Linq.NO_ELEMENTS));
                 }
                 else
                 {
-                    base._observer.OnNext(_lastValue);
-                    base._observer.OnCompleted();
+                    ForwardOnNext(_lastValue);
+                    ForwardOnCompleted();
                 }
-
-                base.Dispose();
             }
         }
     }
@@ -488,7 +432,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
         protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-        internal sealed class _ : Sink<double?>, IObserver<double?>
+        internal sealed class _ : IdentitySink<double?>
         {
             private double? _lastValue;
 
@@ -498,7 +442,7 @@ namespace System.Reactive.Linq.ObservableImpl
                 _lastValue = default(double?);
             }
 
-            public void OnNext(double? value)
+            public override void OnNext(double? value)
             {
                 if (!value.HasValue)
                     return;
@@ -516,17 +460,10 @@ namespace System.Reactive.Linq.ObservableImpl
                 }
             }
 
-            public void OnError(Exception error)
-            {
-                base._observer.OnError(error);
-                base.Dispose();
-            }
-
-            public void OnCompleted()
+            public override void OnCompleted()
             {
-                base._observer.OnNext(_lastValue);
-                base._observer.OnCompleted();
-                base.Dispose();
+                ForwardOnNext(_lastValue);
+                ForwardOnCompleted();
             }
         }
     }
@@ -544,7 +481,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
         protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-        internal sealed class _ : Sink<float?>, IObserver<float?>
+        internal sealed class _ : IdentitySink<float?>
         {
             private float? _lastValue;
 
@@ -554,7 +491,7 @@ namespace System.Reactive.Linq.ObservableImpl
                 _lastValue = default(float?);
             }
 
-            public void OnNext(float? value)
+            public override void OnNext(float? value)
             {
                 if (!value.HasValue)
                     return;
@@ -572,17 +509,10 @@ namespace System.Reactive.Linq.ObservableImpl
                 }
             }
 
-            public void OnError(Exception error)
-            {
-                base._observer.OnError(error);
-                base.Dispose();
-            }
-
-            public void OnCompleted()
+            public override void OnCompleted()
             {
-                base._observer.OnNext(_lastValue);
-                base._observer.OnCompleted();
-                base.Dispose();
+                ForwardOnNext(_lastValue);
+                ForwardOnCompleted();
             }
         }
     }
@@ -600,7 +530,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
         protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-        internal sealed class _ : Sink<decimal?>, IObserver<decimal?>
+        internal sealed class _ : IdentitySink<decimal?>
         {
             private decimal? _lastValue;
 
@@ -610,7 +540,7 @@ namespace System.Reactive.Linq.ObservableImpl
                 _lastValue = default(decimal?);
             }
 
-            public void OnNext(decimal? value)
+            public override void OnNext(decimal? value)
             {
                 if (!value.HasValue)
                     return;
@@ -628,17 +558,10 @@ namespace System.Reactive.Linq.ObservableImpl
                 }
             }
 
-            public void OnError(Exception error)
-            {
-                base._observer.OnError(error);
-                base.Dispose();
-            }
-
-            public void OnCompleted()
+            public override void OnCompleted()
             {
-                base._observer.OnNext(_lastValue);
-                base._observer.OnCompleted();
-                base.Dispose();
+                ForwardOnNext(_lastValue);
+                ForwardOnCompleted();
             }
         }
     }
@@ -656,7 +579,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
         protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-        internal sealed class _ : Sink<int?>, IObserver<int?>
+        internal sealed class _ : IdentitySink<int?>
         {
             private int? _lastValue;
 
@@ -666,7 +589,7 @@ namespace System.Reactive.Linq.ObservableImpl
                 _lastValue = default(int?);
             }
 
-            public void OnNext(int? value)
+            public override void OnNext(int? value)
             {
                 if (!value.HasValue)
                     return;
@@ -684,17 +607,10 @@ namespace System.Reactive.Linq.ObservableImpl
                 }
             }
 
-            public void OnError(Exception error)
-            {
-                base._observer.OnError(error);
-                base.Dispose();
-            }
-
-            public void OnCompleted()
+            public override void OnCompleted()
             {
-                base._observer.OnNext(_lastValue);
-                base._observer.OnCompleted();
-                base.Dispose();
+                ForwardOnNext(_lastValue);
+                ForwardOnCompleted();
             }
         }
     }
@@ -712,7 +628,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
         protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-        internal sealed class _ : Sink<long?>, IObserver<long?>
+        internal sealed class _ : IdentitySink<long?>
         {
             private long? _lastValue;
 
@@ -722,7 +638,7 @@ namespace System.Reactive.Linq.ObservableImpl
                 _lastValue = default(long?);
             }
 
-            public void OnNext(long? value)
+            public override void OnNext(long? value)
             {
                 if (!value.HasValue)
                     return;
@@ -740,17 +656,10 @@ namespace System.Reactive.Linq.ObservableImpl
                 }
             }
 
-            public void OnError(Exception error)
-            {
-                base._observer.OnError(error);
-                base.Dispose();
-            }
-
-            public void OnCompleted()
+            public override void OnCompleted()
             {
-                base._observer.OnNext(_lastValue);
-                base._observer.OnCompleted();
-                base.Dispose();
+                ForwardOnNext(_lastValue);
+                ForwardOnCompleted();
             }
         }
     }

+ 7 - 16
Rx.NET/Source/src/System.Reactive/Linq/Observable/MinBy.cs

@@ -23,7 +23,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
         protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-        internal sealed class _ : Sink<IList<TSource>>, IObserver<TSource>
+        internal sealed class _ : Sink<TSource, IList<TSource>> 
         {
             private readonly MinBy<TSource, TKey> _parent;
             private bool _hasValue;
@@ -40,7 +40,7 @@ namespace System.Reactive.Linq.ObservableImpl
                 _list = new List<TSource>();
             }
 
-            public void OnNext(TSource value)
+            public override void OnNext(TSource value)
             {
                 var key = default(TKey);
                 try
@@ -49,8 +49,7 @@ namespace System.Reactive.Linq.ObservableImpl
                 }
                 catch (Exception ex)
                 {
-                    base._observer.OnError(ex);
-                    base.Dispose();
+                    ForwardOnError(ex);
                     return;
                 }
 
@@ -69,8 +68,7 @@ namespace System.Reactive.Linq.ObservableImpl
                     }
                     catch (Exception ex)
                     {
-                        base._observer.OnError(ex);
-                        base.Dispose();
+                        ForwardOnError(ex);
                         return;
                     }
                 }
@@ -87,17 +85,10 @@ namespace System.Reactive.Linq.ObservableImpl
                 }
             }
 
-            public void OnError(Exception error)
+            public override void OnCompleted()
             {
-                base._observer.OnError(error);
-                base.Dispose();
-            }
-
-            public void OnCompleted()
-            {
-                base._observer.OnNext(_list);
-                base._observer.OnCompleted();
-                base.Dispose();
+                ForwardOnNext(_list);
+                ForwardOnCompleted();
             }
         }
     }

+ 2 - 20
Rx.NET/Source/src/System.Reactive/Linq/Observable/Multicast.cs

@@ -24,7 +24,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
         protected override IDisposable Run(_ sink) => sink.Run(this);
 
-        internal sealed class _ : Sink<TResult>, IObserver<TResult>
+        internal sealed class _ : IdentitySink<TResult>
         {
             public _(IObserver<TResult> observer, IDisposable cancel)
                 : base(observer, cancel)
@@ -43,8 +43,7 @@ namespace System.Reactive.Linq.ObservableImpl
                 }
                 catch (Exception exception)
                 {
-                    base._observer.OnError(exception);
-                    base.Dispose();
+                    ForwardOnError(exception);
                     return Disposable.Empty;
                 }
 
@@ -53,23 +52,6 @@ namespace System.Reactive.Linq.ObservableImpl
 
                 return StableCompositeDisposable.Create(subscription, connection);
             }
-
-            public void OnNext(TResult value)
-            {
-                base._observer.OnNext(value);
-            }
-
-            public void OnError(Exception error)
-            {
-                base._observer.OnError(error);
-                base.Dispose();
-            }
-
-            public void OnCompleted()
-            {
-                base._observer.OnCompleted();
-                base.Dispose();
-            }
         }
     }
 }

+ 3 - 15
Rx.NET/Source/src/System.Reactive/Linq/Observable/OfType.cs

@@ -17,32 +17,20 @@ namespace System.Reactive.Linq.ObservableImpl
 
         protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-        internal sealed class _ : Sink<TResult>, IObserver<TSource>
+        internal sealed class _ : Sink<TSource, TResult> 
         {
             public _(IObserver<TResult> observer, IDisposable cancel)
                 : base(observer, cancel)
             {
             }
 
-            public void OnNext(TSource value)
+            public override void OnNext(TSource value)
             {
                 if (value is TResult)
                 {
-                    base._observer.OnNext((TResult)(object)value);
+                    ForwardOnNext((TResult)(object)value);
                 }
             }
-
-            public void OnError(Exception error)
-            {
-                base._observer.OnError(error);
-                base.Dispose();
-            }
-
-            public void OnCompleted()
-            {
-                base._observer.OnCompleted();
-                base.Dispose();
-            }
         }
     }
 }

+ 0 - 5
Rx.NET/Source/src/System.Reactive/Linq/Observable/OnErrorResumeNext.cs

@@ -34,11 +34,6 @@ namespace System.Reactive.Linq.ObservableImpl
                 return null;
             }
 
-            public override void OnNext(TSource value)
-            {
-                base._observer.OnNext(value);
-            }
-
             public override void OnError(Exception error)
             {
                 Recurse();

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

@@ -24,7 +24,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
         protected override IDisposable Run(_ sink) => sink.Run(_scheduler);
 
-        internal sealed class _ : Sink<int>
+        internal sealed class _ : IdentitySink<int>
         {
             private readonly int _start;
             private readonly int _count;
@@ -53,27 +53,24 @@ namespace System.Reactive.Linq.ObservableImpl
             {
                 while (!cancel.IsDisposed && i < _count)
                 {
-                    base._observer.OnNext(_start + i);
+                    ForwardOnNext(_start + i);
                     i++;
                 }
 
                 if (!cancel.IsDisposed)
-                    base._observer.OnCompleted();
-
-                base.Dispose();
+                    ForwardOnCompleted();
             }
 
             private void LoopRec(int i, Action<int> recurse)
             {
                 if (i < _count)
                 {
-                    base._observer.OnNext(_start + i);
+                    ForwardOnNext(_start + i);
                     recurse(i + 1);
                 }
                 else
                 {
-                    base._observer.OnCompleted();
-                    base.Dispose();
+                    ForwardOnCompleted();
                 }
             }
         }

+ 1 - 18
Rx.NET/Source/src/System.Reactive/Linq/Observable/RefCount.cs

@@ -27,7 +27,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
         protected override IDisposable Run(_ sink) => sink.Run(this);
 
-        internal sealed class _ : Sink<TSource>, IObserver<TSource>
+        internal sealed class _ : IdentitySink<TSource>
         {
             public _(IObserver<TSource> observer, IDisposable cancel)
                 : base(observer, cancel)
@@ -59,23 +59,6 @@ namespace System.Reactive.Linq.ObservableImpl
                     }
                 });
             }
-
-            public void OnNext(TSource value)
-            {
-                base._observer.OnNext(value);
-            }
-
-            public void OnError(Exception error)
-            {
-                base._observer.OnError(error);
-                base.Dispose();
-            }
-
-            public void OnCompleted()
-            {
-                base._observer.OnCompleted();
-                base.Dispose();
-            }
         }
     }
 }

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

@@ -24,7 +24,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
             protected override IDisposable Run(_ sink) => sink.Run(this);
 
-            internal sealed class _ : Sink<TResult>
+            internal sealed class _ : IdentitySink<TResult>
             {
                 private readonly TResult _value;
 
@@ -49,7 +49,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
                 private void LoopRecInf(Action recurse)
                 {
-                    base._observer.OnNext(_value);
+                    ForwardOnNext(_value);
                     recurse();
                 }
 
@@ -57,7 +57,7 @@ namespace System.Reactive.Linq.ObservableImpl
                 {
                     var value = _value;
                     while (!cancel.IsDisposed)
-                        base._observer.OnNext(value);
+                        ForwardOnNext(value);
 
                     base.Dispose();
                 }
@@ -81,7 +81,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
             protected override IDisposable Run(_ sink) => sink.Run(this);
 
-            internal sealed class _ : Sink<TResult>
+            internal sealed class _ : IdentitySink<TResult>
             {
                 private readonly TResult _value;
 
@@ -108,14 +108,13 @@ namespace System.Reactive.Linq.ObservableImpl
                 {
                     if (n > 0)
                     {
-                        base._observer.OnNext(_value);
+                        ForwardOnNext(_value);
                         n--;
                     }
 
                     if (n == 0)
                     {
-                        base._observer.OnCompleted();
-                        base.Dispose();
+                        ForwardOnCompleted();
                         return;
                     }
 
@@ -127,14 +126,12 @@ namespace System.Reactive.Linq.ObservableImpl
                     var value = _value;
                     while (n > 0 && !cancel.IsDisposed)
                     {
-                        base._observer.OnNext(value);
+                        ForwardOnNext(value);
                         n--;
                     }
 
                     if (!cancel.IsDisposed)
-                        base._observer.OnCompleted();
-
-                    base.Dispose();
+                        ForwardOnCompleted();
                 }
             }
         }

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

@@ -21,7 +21,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
         protected override IDisposable Run(_ sink) => sink.Run(_scheduler);
 
-        internal sealed class _ : Sink<TResult>
+        internal sealed class _ : IdentitySink<TResult>
         {
             private readonly TResult _value;
 
@@ -38,9 +38,8 @@ namespace System.Reactive.Linq.ObservableImpl
 
             private void Invoke()
             {
-                base._observer.OnNext(_value);
-                base._observer.OnCompleted();
-                base.Dispose();
+                ForwardOnNext(_value);
+                ForwardOnCompleted();
             }
         }
     }

+ 18 - 27
Rx.NET/Source/src/System.Reactive/Linq/Observable/Sample.cs

@@ -22,7 +22,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
         protected override IDisposable Run(_ sink) => sink.Run(this);
 
-        internal sealed class _ : Sink<TSource>, IObserver<TSource>
+        internal sealed class _ : IdentitySink<TSource>
         {
             private readonly object _gate = new object();
 
@@ -52,7 +52,7 @@ namespace System.Reactive.Linq.ObservableImpl
                 return StableCompositeDisposable.Create(_sourceSubscription, _samplerSubscription);
             }
 
-            public void OnNext(TSource value)
+            public override void OnNext(TSource value)
             {
                 lock (_gate)
                 {
@@ -61,26 +61,22 @@ namespace System.Reactive.Linq.ObservableImpl
                 }
             }
 
-            public void OnError(Exception error)
+            public override void OnError(Exception error)
             {
                 lock (_gate)
                 {
-                    base._observer.OnError(error);
-                    base.Dispose();
+                    ForwardOnError(error);
                 }
             }
 
-            public void OnCompleted()
+            public override void OnCompleted()
             {
                 lock (_gate)
                 {
                     _sourceAtEnd = true;
 
                     if (_samplerAtEnd)
-                    {
-                        base._observer.OnCompleted();
-                        base.Dispose();
-                    }
+                        ForwardOnCompleted();
                     else
                         _sourceSubscription.Dispose();
                 }
@@ -102,13 +98,12 @@ namespace System.Reactive.Linq.ObservableImpl
                         if (_parent._hasValue)
                         {
                             _parent._hasValue = false;
-                            _parent._observer.OnNext(_parent._value);
+                            _parent.ForwardOnNext(_parent._value);
                         }
 
                         if (_parent._sourceAtEnd)
                         {
-                            _parent._observer.OnCompleted();
-                            _parent.Dispose();
+                            _parent.ForwardOnCompleted();
                         }
                     }
                 }
@@ -118,8 +113,7 @@ namespace System.Reactive.Linq.ObservableImpl
                     // BREAKING CHANGE v2 > v1.x - This error used to be swallowed
                     lock (_parent._gate)
                     {
-                        _parent._observer.OnError(error);
-                        _parent.Dispose();
+                        _parent.ForwardOnError(error);
                     }
                 }
 
@@ -132,13 +126,12 @@ namespace System.Reactive.Linq.ObservableImpl
                         if (_parent._hasValue)
                         {
                             _parent._hasValue = false;
-                            _parent._observer.OnNext(_parent._value);
+                            _parent.ForwardOnNext(_parent._value);
                         }
 
                         if (_parent._sourceAtEnd)
                         {
-                            _parent._observer.OnCompleted();
-                            _parent.Dispose();
+                            _parent.ForwardOnCompleted();
                         }
                         else
                             _parent._samplerSubscription.Dispose();
@@ -165,7 +158,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
         protected override IDisposable Run(_ sink) => sink.Run(this);
 
-        internal sealed class _ : Sink<TSource>, IObserver<TSource>
+        internal sealed class _ : IdentitySink<TSource>
         {
             private object _gate = new object();
 
@@ -199,18 +192,17 @@ namespace System.Reactive.Linq.ObservableImpl
                     if (_hasValue)
                     {
                         _hasValue = false;
-                        base._observer.OnNext(_value);
+                        ForwardOnNext(_value);
                     }
 
                     if (_atEnd)
                     {
-                        base._observer.OnCompleted();
-                        base.Dispose();
+                        ForwardOnCompleted();
                     }
                 }
             }
 
-            public void OnNext(TSource value)
+            public override void OnNext(TSource value)
             {
                 lock (_gate)
                 {
@@ -219,16 +211,15 @@ namespace System.Reactive.Linq.ObservableImpl
                 }
             }
 
-            public void OnError(Exception error)
+            public override void OnError(Exception error)
             {
                 lock (_gate)
                 {
-                    base._observer.OnError(error);
-                    base.Dispose();
+                    ForwardOnError(error);
                 }
             }
 
-            public void OnCompleted()
+            public override void OnCompleted()
             {
                 lock (_gate)
                 {

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

@@ -21,7 +21,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
         protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-        internal sealed class _ : Sink<TAccumulate>, IObserver<TSource>
+        internal sealed class _ : Sink<TSource, TAccumulate> 
         {
             private readonly Func<TAccumulate, TSource, TAccumulate> _accumulator;
             private TAccumulate _accumulation;
@@ -33,7 +33,7 @@ namespace System.Reactive.Linq.ObservableImpl
                 _accumulation = parent._seed;
             }
 
-            public void OnNext(TSource value)
+            public override void OnNext(TSource value)
             {
                 try
                 {
@@ -41,24 +41,11 @@ namespace System.Reactive.Linq.ObservableImpl
                 }
                 catch (Exception exception)
                 {
-                    base._observer.OnError(exception);
-                    base.Dispose();
+                    ForwardOnError(exception);
                     return;
                 }
 
-                base._observer.OnNext(_accumulation);
-            }
-
-            public void OnError(Exception error)
-            {
-                base._observer.OnError(error);
-                base.Dispose();
-            }
-
-            public void OnCompleted()
-            {
-                base._observer.OnCompleted();
-                base.Dispose();
+                ForwardOnNext(_accumulation);
             }
         }
     }
@@ -78,7 +65,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
         protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-        internal sealed class _ : Sink<TSource>, IObserver<TSource>
+        internal sealed class _ : IdentitySink<TSource>
         {
             private readonly Func<TSource, TSource, TSource> _accumulator;
             private TSource _accumulation;
@@ -92,7 +79,7 @@ namespace System.Reactive.Linq.ObservableImpl
                 _hasAccumulation = false;
             }
 
-            public void OnNext(TSource value)
+            public override void OnNext(TSource value)
             {
                 try
                 {
@@ -108,24 +95,11 @@ namespace System.Reactive.Linq.ObservableImpl
                 }
                 catch (Exception exception)
                 {
-                    base._observer.OnError(exception);
-                    base.Dispose();
+                    ForwardOnError(exception);
                     return;
                 }
 
-                base._observer.OnNext(_accumulation);
-            }
-
-            public void OnError(Exception error)
-            {
-                base._observer.OnError(error);
-                base.Dispose();
-            }
-
-            public void OnCompleted()
-            {
-                base._observer.OnCompleted();
-                base.Dispose();
+                ForwardOnNext(_accumulation);
             }
         }
     }

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

@@ -21,7 +21,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
             protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-            internal sealed class _ : Sink<TResult>, IObserver<TSource>
+            internal sealed class _ : Sink<TSource, TResult> 
             {
                 private readonly Func<TSource, TResult> _selector;
 
@@ -31,7 +31,7 @@ namespace System.Reactive.Linq.ObservableImpl
                     _selector = selector;
                 }
 
-                public void OnNext(TSource value)
+                public override void OnNext(TSource value)
                 {
                     var result = default(TResult);
                     try
@@ -40,24 +40,11 @@ namespace System.Reactive.Linq.ObservableImpl
                     }
                     catch (Exception exception)
                     {
-                        base._observer.OnError(exception);
-                        base.Dispose();
+                        ForwardOnError(exception);
                         return;
                     }
 
-                    base._observer.OnNext(result);
-                }
-
-                public void OnError(Exception error)
-                {
-                    base._observer.OnError(error);
-                    base.Dispose();
-                }
-
-                public void OnCompleted()
-                {
-                    base._observer.OnCompleted();
-                    base.Dispose();
+                    ForwardOnNext(result);
                 }
             }
         }
@@ -77,7 +64,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
             protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-            internal sealed class _ : Sink<TResult>, IObserver<TSource>
+            internal sealed class _ : Sink<TSource, TResult> 
             {
                 private readonly Func<TSource, int, TResult> _selector;
                 private int _index;
@@ -89,7 +76,7 @@ namespace System.Reactive.Linq.ObservableImpl
                     _index = 0;
                 }
 
-                public void OnNext(TSource value)
+                public override void OnNext(TSource value)
                 {
                     var result = default(TResult);
                     try
@@ -98,24 +85,11 @@ namespace System.Reactive.Linq.ObservableImpl
                     }
                     catch (Exception exception)
                     {
-                        base._observer.OnError(exception);
-                        base.Dispose();
+                        ForwardOnError(exception);
                         return;
                     }
 
-                    base._observer.OnNext(result);
-                }
-
-                public void OnError(Exception error)
-                {
-                    base._observer.OnError(error);
-                    base.Dispose();
-                }
-
-                public void OnCompleted()
-                {
-                    base._observer.OnCompleted();
-                    base.Dispose();
+                    ForwardOnNext(result);
                 }
             }
         }

ファイルの差分が大きいため隠しています
+ 106 - 210
Rx.NET/Source/src/System.Reactive/Linq/Observable/SelectMany.cs


+ 31 - 54
Rx.NET/Source/src/System.Reactive/Linq/Observable/SequenceEqual.cs

@@ -26,7 +26,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
             protected override IDisposable Run(_ sink) => sink.Run(this);
 
-            internal sealed class _ : Sink<bool>
+            internal sealed class _ : IdentitySink<bool>
             {
                 private readonly IEqualityComparer<TSource> _comparer;
 
@@ -80,22 +80,19 @@ namespace System.Reactive.Linq.ObservableImpl
                                 }
                                 catch (Exception exception)
                                 {
-                                    _parent._observer.OnError(exception);
-                                    _parent.Dispose();
+                                    _parent.ForwardOnError(exception);
                                     return;
                                 }
                                 if (!equal)
                                 {
-                                    _parent._observer.OnNext(false);
-                                    _parent._observer.OnCompleted();
-                                    _parent.Dispose();
+                                    _parent.ForwardOnNext(false);
+                                    _parent.ForwardOnCompleted();
                                 }
                             }
                             else if (_parent._doner)
                             {
-                                _parent._observer.OnNext(false);
-                                _parent._observer.OnCompleted();
-                                _parent.Dispose();
+                                _parent.ForwardOnNext(false);
+                                _parent.ForwardOnCompleted();
                             }
                             else
                                 _parent._ql.Enqueue(value);
@@ -106,8 +103,7 @@ namespace System.Reactive.Linq.ObservableImpl
                     {
                         lock (_parent._gate)
                         {
-                            _parent._observer.OnError(error);
-                            _parent.Dispose();
+                            _parent.ForwardOnError(error);
                         }
                     }
 
@@ -120,15 +116,13 @@ namespace System.Reactive.Linq.ObservableImpl
                             {
                                 if (_parent._qr.Count > 0)
                                 {
-                                    _parent._observer.OnNext(false);
-                                    _parent._observer.OnCompleted();
-                                    _parent.Dispose();
+                                    _parent.ForwardOnNext(false);
+                                    _parent.ForwardOnCompleted();
                                 }
                                 else if (_parent._doner)
                                 {
-                                    _parent._observer.OnNext(true);
-                                    _parent._observer.OnCompleted();
-                                    _parent.Dispose();
+                                    _parent.ForwardOnNext(true);
+                                    _parent.ForwardOnCompleted();
                                 }
                             }
                         }
@@ -158,22 +152,19 @@ namespace System.Reactive.Linq.ObservableImpl
                                 }
                                 catch (Exception exception)
                                 {
-                                    _parent._observer.OnError(exception);
-                                    _parent.Dispose();
+                                    _parent.ForwardOnError(exception);
                                     return;
                                 }
                                 if (!equal)
                                 {
-                                    _parent._observer.OnNext(false);
-                                    _parent._observer.OnCompleted();
-                                    _parent.Dispose();
+                                    _parent.ForwardOnNext(false);
+                                    _parent.ForwardOnCompleted();
                                 }
                             }
                             else if (_parent._donel)
                             {
-                                _parent._observer.OnNext(false);
-                                _parent._observer.OnCompleted();
-                                _parent.Dispose();
+                                _parent.ForwardOnNext(false);
+                                _parent.ForwardOnCompleted();
                             }
                             else
                                 _parent._qr.Enqueue(value);
@@ -184,8 +175,7 @@ namespace System.Reactive.Linq.ObservableImpl
                     {
                         lock (_parent._gate)
                         {
-                            _parent._observer.OnError(error);
-                            _parent.Dispose();
+                            _parent.ForwardOnError(error);
                         }
                     }
 
@@ -198,15 +188,13 @@ namespace System.Reactive.Linq.ObservableImpl
                             {
                                 if (_parent._ql.Count > 0)
                                 {
-                                    _parent._observer.OnNext(false);
-                                    _parent._observer.OnCompleted();
-                                    _parent.Dispose();
+                                    _parent.ForwardOnNext(false);
+                                    _parent.ForwardOnCompleted();
                                 }
                                 else if (_parent._donel)
                                 {
-                                    _parent._observer.OnNext(true);
-                                    _parent._observer.OnCompleted();
-                                    _parent.Dispose();
+                                    _parent.ForwardOnNext(true);
+                                    _parent.ForwardOnCompleted();
                                 }
                             }
                         }
@@ -232,7 +220,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
             protected override IDisposable Run(_ sink) => sink.Run(this);
 
-            internal sealed class _ : Sink<bool>, IObserver<TSource>
+            internal sealed class _ : Sink<TSource, bool> 
             {
                 private readonly IEqualityComparer<TSource> _comparer;
 
@@ -259,8 +247,7 @@ namespace System.Reactive.Linq.ObservableImpl
                     }
                     catch (Exception exception)
                     {
-                        base._observer.OnError(exception);
-                        base.Dispose();
+                        ForwardOnError(exception);
                         return Disposable.Empty;
                     }
 
@@ -270,7 +257,7 @@ namespace System.Reactive.Linq.ObservableImpl
                     );
                 }
 
-                public void OnNext(TSource value)
+                public override void OnNext(TSource value)
                 {
                     var equal = false;
 
@@ -284,26 +271,18 @@ namespace System.Reactive.Linq.ObservableImpl
                     }
                     catch (Exception exception)
                     {
-                        base._observer.OnError(exception);
-                        base.Dispose();
+                        ForwardOnError(exception);
                         return;
                     }
 
                     if (!equal)
                     {
-                        base._observer.OnNext(false);
-                        base._observer.OnCompleted();
-                        base.Dispose();
+                        ForwardOnNext(false);
+                        ForwardOnCompleted();
                     }
                 }
 
-                public void OnError(Exception error)
-                {
-                    base._observer.OnError(error);
-                    base.Dispose();
-                }
-
-                public void OnCompleted()
+                public override void OnCompleted()
                 {
                     var hasNext = false;
 
@@ -313,14 +292,12 @@ namespace System.Reactive.Linq.ObservableImpl
                     }
                     catch (Exception exception)
                     {
-                        base._observer.OnError(exception);
-                        base.Dispose();
+                        ForwardOnError(exception);
                         return;
                     }
 
-                    base._observer.OnNext(!hasNext);
-                    base._observer.OnCompleted();
-                    base.Dispose();
+                    ForwardOnNext(!hasNext);
+                    ForwardOnCompleted();
                 }
             }
         }

+ 15 - 34
Rx.NET/Source/src/System.Reactive/Linq/Observable/SingleAsync.cs

@@ -19,7 +19,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
             protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-            internal sealed class _ : Sink<TSource>, IObserver<TSource>
+            internal sealed class _ : IdentitySink<TSource>
             {
                 private TSource _value;
                 private bool _seenValue;
@@ -31,12 +31,11 @@ namespace System.Reactive.Linq.ObservableImpl
                     _seenValue = false;
                 }
 
-                public void OnNext(TSource value)
+                public override void OnNext(TSource value)
                 {
                     if (_seenValue)
                     {
-                        base._observer.OnError(new InvalidOperationException(Strings_Linq.MORE_THAN_ONE_ELEMENT));
-                        base.Dispose();
+                        ForwardOnError(new InvalidOperationException(Strings_Linq.MORE_THAN_ONE_ELEMENT));
                         return;
                     }
 
@@ -44,25 +43,17 @@ namespace System.Reactive.Linq.ObservableImpl
                     _seenValue = true;
                 }
 
-                public void OnError(Exception error)
-                {
-                    base._observer.OnError(error);
-                    base.Dispose();
-                }
-
-                public void OnCompleted()
+                public override void OnCompleted()
                 {
                     if (!_seenValue)
                     {
-                        base._observer.OnError(new InvalidOperationException(Strings_Linq.NO_ELEMENTS));
+                        ForwardOnError(new InvalidOperationException(Strings_Linq.NO_ELEMENTS));
                     }
                     else
                     {
-                        base._observer.OnNext(_value);
-                        base._observer.OnCompleted();
+                        ForwardOnNext(_value);
+                        ForwardOnCompleted();
                     }
-
-                    base.Dispose();
                 }
             }
         }
@@ -82,7 +73,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
             protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-            internal sealed class _ : Sink<TSource>, IObserver<TSource>
+            internal sealed class _ : IdentitySink<TSource>
             {
                 private readonly Func<TSource, bool> _predicate;
                 private TSource _value;
@@ -97,7 +88,7 @@ namespace System.Reactive.Linq.ObservableImpl
                     _seenValue = false;
                 }
 
-                public void OnNext(TSource value)
+                public override void OnNext(TSource value)
                 {
                     var b = false;
 
@@ -107,8 +98,7 @@ namespace System.Reactive.Linq.ObservableImpl
                     }
                     catch (Exception ex)
                     {
-                        base._observer.OnError(ex);
-                        base.Dispose();
+                        ForwardOnError(ex);
                         return;
                     }
 
@@ -116,8 +106,7 @@ namespace System.Reactive.Linq.ObservableImpl
                     {
                         if (_seenValue)
                         {
-                            base._observer.OnError(new InvalidOperationException(Strings_Linq.MORE_THAN_ONE_MATCHING_ELEMENT));
-                            base.Dispose();
+                            ForwardOnError(new InvalidOperationException(Strings_Linq.MORE_THAN_ONE_MATCHING_ELEMENT));
                             return;
                         }
 
@@ -126,25 +115,17 @@ namespace System.Reactive.Linq.ObservableImpl
                     }
                 }
 
-                public void OnError(Exception error)
-                {
-                    base._observer.OnError(error);
-                    base.Dispose();
-                }
-
-                public void OnCompleted()
+                public override void OnCompleted()
                 {
                     if (!_seenValue)
                     {
-                        base._observer.OnError(new InvalidOperationException(Strings_Linq.NO_MATCHING_ELEMENTS));
+                        ForwardOnError(new InvalidOperationException(Strings_Linq.NO_MATCHING_ELEMENTS));
                     }
                     else
                     {
-                        base._observer.OnNext(_value);
-                        base._observer.OnCompleted();
+                        ForwardOnNext(_value);
+                        ForwardOnCompleted();
                     }
-
-                    base.Dispose();
                 }
             }
         }

+ 13 - 30
Rx.NET/Source/src/System.Reactive/Linq/Observable/SingleOrDefaultAsync.cs

@@ -19,7 +19,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
             protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-            internal sealed class _ : Sink<TSource>, IObserver<TSource>
+            internal sealed class _ : IdentitySink<TSource>
             {
                 private TSource _value;
                 private bool _seenValue;
@@ -31,12 +31,11 @@ namespace System.Reactive.Linq.ObservableImpl
                     _seenValue = false;
                 }
 
-                public void OnNext(TSource value)
+                public override void OnNext(TSource value)
                 {
                     if (_seenValue)
                     {
-                        base._observer.OnError(new InvalidOperationException(Strings_Linq.MORE_THAN_ONE_ELEMENT));
-                        base.Dispose();
+                        ForwardOnError(new InvalidOperationException(Strings_Linq.MORE_THAN_ONE_ELEMENT));
                         return;
                     }
 
@@ -44,17 +43,10 @@ namespace System.Reactive.Linq.ObservableImpl
                     _seenValue = true;
                 }
 
-                public void OnError(Exception error)
+                public override void OnCompleted()
                 {
-                    base._observer.OnError(error);
-                    base.Dispose();
-                }
-
-                public void OnCompleted()
-                {
-                    base._observer.OnNext(_value);
-                    base._observer.OnCompleted();
-                    base.Dispose();
+                    ForwardOnNext(_value);
+                    ForwardOnCompleted();
                 }
             }
         }
@@ -74,7 +66,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
             protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-            internal sealed class _ : Sink<TSource>, IObserver<TSource>
+            internal sealed class _ : IdentitySink<TSource>
             {
                 private readonly Func<TSource, bool> _predicate;
                 private TSource _value;
@@ -89,7 +81,7 @@ namespace System.Reactive.Linq.ObservableImpl
                     _seenValue = false;
                 }
 
-                public void OnNext(TSource value)
+                public override void OnNext(TSource value)
                 {
                     var b = false;
 
@@ -99,8 +91,7 @@ namespace System.Reactive.Linq.ObservableImpl
                     }
                     catch (Exception ex)
                     {
-                        base._observer.OnError(ex);
-                        base.Dispose();
+                        ForwardOnError(ex);
                         return;
                     }
 
@@ -108,8 +99,7 @@ namespace System.Reactive.Linq.ObservableImpl
                     {
                         if (_seenValue)
                         {
-                            base._observer.OnError(new InvalidOperationException(Strings_Linq.MORE_THAN_ONE_MATCHING_ELEMENT));
-                            base.Dispose();
+                            ForwardOnError(new InvalidOperationException(Strings_Linq.MORE_THAN_ONE_MATCHING_ELEMENT));
                             return;
                         }
 
@@ -118,17 +108,10 @@ namespace System.Reactive.Linq.ObservableImpl
                     }
                 }
 
-                public void OnError(Exception error)
-                {
-                    base._observer.OnError(error);
-                    base.Dispose();
-                }
-
-                public void OnCompleted()
+                public override void OnCompleted()
                 {
-                    base._observer.OnNext(_value);
-                    base._observer.OnCompleted();
-                    base.Dispose();
+                    ForwardOnNext(_value);
+                    ForwardOnCompleted();
                 }
             }
         }

+ 6 - 30
Rx.NET/Source/src/System.Reactive/Linq/Observable/Skip.cs

@@ -36,7 +36,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
             protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-            internal sealed class _ : Sink<TSource>, IObserver<TSource>
+            internal sealed class _ : IdentitySink<TSource>
             {
                 private int _remaining;
 
@@ -46,25 +46,13 @@ namespace System.Reactive.Linq.ObservableImpl
                     _remaining = count;
                 }
 
-                public void OnNext(TSource value)
+                public override void OnNext(TSource value)
                 {
                     if (_remaining <= 0)
-                        base._observer.OnNext(value);
+                        ForwardOnNext(value);
                     else
                         _remaining--;
                 }
-
-                public void OnError(Exception error)
-                {
-                    base._observer.OnError(error);
-                    base.Dispose();
-                }
-
-                public void OnCompleted()
-                {
-                    base._observer.OnCompleted();
-                    base.Dispose();
-                }
             }
         }
 
@@ -102,7 +90,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
             protected override IDisposable Run(_ sink) => sink.Run(this);
 
-            internal sealed class _ : Sink<TSource>, IObserver<TSource>
+            internal sealed class _ : IdentitySink<TSource>
             {
                 private volatile bool _open;
 
@@ -123,22 +111,10 @@ namespace System.Reactive.Linq.ObservableImpl
                     _open = true;
                 }
 
-                public void OnNext(TSource value)
+                public override void OnNext(TSource value)
                 {
                     if (_open)
-                        base._observer.OnNext(value);
-                }
-
-                public void OnError(Exception error)
-                {
-                    base._observer.OnError(error);
-                    base.Dispose();
-                }
-
-                public void OnCompleted()
-                {
-                    base._observer.OnCompleted();
-                    base.Dispose();
+                        ForwardOnNext(value);
                 }
             }
         }

+ 9 - 28
Rx.NET/Source/src/System.Reactive/Linq/Observable/SkipLast.cs

@@ -24,7 +24,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
             protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-            internal sealed class _ : Sink<TSource>, IObserver<TSource>
+            internal sealed class _ : IdentitySink<TSource>
             {
                 private int _count;
                 private Queue<TSource> _queue;
@@ -36,23 +36,11 @@ namespace System.Reactive.Linq.ObservableImpl
                     _queue = new Queue<TSource>();
                 }
 
-                public void OnNext(TSource value)
+                public override void OnNext(TSource value)
                 {
                     _queue.Enqueue(value);
                     if (_queue.Count > _count)
-                        base._observer.OnNext(_queue.Dequeue());
-                }
-
-                public void OnError(Exception error)
-                {
-                    base._observer.OnError(error);
-                    base.Dispose();
-                }
-
-                public void OnCompleted()
-                {
-                    base._observer.OnCompleted();
-                    base.Dispose();
+                        ForwardOnNext(_queue.Dequeue());
                 }
             }
         }
@@ -74,7 +62,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
             protected override IDisposable Run(_ sink) => sink.Run(this);
 
-            internal sealed class _ : Sink<TSource>, IObserver<TSource>
+            internal sealed class _ : IdentitySink<TSource>
             {
                 private readonly TimeSpan _duration;
                 private Queue<System.Reactive.TimeInterval<TSource>> _queue;
@@ -95,28 +83,21 @@ namespace System.Reactive.Linq.ObservableImpl
                     return parent._source.SubscribeSafe(this);
                 }
 
-                public void OnNext(TSource value)
+                public override void OnNext(TSource value)
                 {
                     var now = _watch.Elapsed;
                     _queue.Enqueue(new System.Reactive.TimeInterval<TSource>(value, now));
                     while (_queue.Count > 0 && now - _queue.Peek().Interval >= _duration)
-                        base._observer.OnNext(_queue.Dequeue().Value);
-                }
-
-                public void OnError(Exception error)
-                {
-                    base._observer.OnError(error);
-                    base.Dispose();
+                        ForwardOnNext(_queue.Dequeue().Value);
                 }
 
-                public void OnCompleted()
+                public override void OnCompleted()
                 {
                     var now = _watch.Elapsed;
                     while (_queue.Count > 0 && now - _queue.Peek().Interval >= _duration)
-                        base._observer.OnNext(_queue.Dequeue().Value);
+                        ForwardOnNext(_queue.Dequeue().Value);
 
-                    base._observer.OnCompleted();
-                    base.Dispose();
+                    ForwardOnCompleted();
                 }
             }
         }

+ 13 - 25
Rx.NET/Source/src/System.Reactive/Linq/Observable/SkipUntil.cs

@@ -22,7 +22,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
         protected override IDisposable Run(_ sink) => sink.Run(this);
 
-        internal sealed class _ : Sink<TSource>
+        internal sealed class _ : IdentitySink<TSource>
         {
             public _(IObserver<TSource> observer, IDisposable cancel)
                 : base(observer, cancel)
@@ -49,13 +49,12 @@ namespace System.Reactive.Linq.ObservableImpl
             private sealed class SourceObserver : IObserver<TSource>
             {
                 private readonly _ _parent;
-                public volatile IObserver<TSource> _observer;
+                public volatile bool _forward;
                 private readonly SingleAssignmentDisposable _subscription;
 
                 public SourceObserver(_ parent)
                 {
                     _parent = parent;
-                    _observer = NopObserver<TSource>.Instance;
                     _subscription = new SingleAssignmentDisposable();
                 }
 
@@ -66,18 +65,20 @@ namespace System.Reactive.Linq.ObservableImpl
 
                 public void OnNext(TSource value)
                 {
-                    _observer.OnNext(value);
+                    if (_forward)
+                        _parent.ForwardOnNext(value);
                 }
 
                 public void OnError(Exception error)
                 {
-                    _parent._observer.OnError(error);
-                    _parent.Dispose();
+                    _parent.ForwardOnError(error);
                 }
 
                 public void OnCompleted()
                 {
-                    _observer.OnCompleted();
+                    if (_forward)
+                        _parent.ForwardOnCompleted();
+
                     _subscription.Dispose(); // We can't cancel the other stream yet, it may be on its way to dispatch an OnError message and we don't want to have a race.
                 }
             }
@@ -102,14 +103,13 @@ namespace System.Reactive.Linq.ObservableImpl
 
                 public void OnNext(TOther value)
                 {
-                    _sourceObserver._observer = _parent._observer;
+                    _sourceObserver._forward = true;
                     _subscription.Dispose();
                 }
 
                 public void OnError(Exception error)
                 {
-                    _parent._observer.OnError(error);
-                    _parent.Dispose();
+                    _parent.ForwardOnError(error);
                 }
 
                 public void OnCompleted()
@@ -154,7 +154,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
         protected override IDisposable Run(_ sink) => sink.Run(this);
 
-        internal sealed class _ : Sink<TSource>, IObserver<TSource>
+        internal sealed class _ : IdentitySink<TSource>
         {
             private volatile bool _open;
 
@@ -175,22 +175,10 @@ namespace System.Reactive.Linq.ObservableImpl
                 _open = true;
             }
 
-            public void OnNext(TSource value)
+            public override void OnNext(TSource value)
             {
                 if (_open)
-                    base._observer.OnNext(value);
-            }
-
-            public void OnError(Exception error)
-            {
-                base._observer.OnError(error);
-                base.Dispose();
-            }
-
-            public void OnCompleted()
-            {
-                base._observer.OnCompleted();
-                base.Dispose();
+                    ForwardOnNext(value);
             }
         }
     }

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

@@ -21,7 +21,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
             protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-            internal sealed class _ : Sink<TSource>, IObserver<TSource>
+            internal sealed class _ : IdentitySink<TSource>
             {
                 private Func<TSource, bool> _predicate;
 
@@ -31,7 +31,7 @@ namespace System.Reactive.Linq.ObservableImpl
                     _predicate = predicate;
                 }
 
-                public void OnNext(TSource value)
+                public override void OnNext(TSource value)
                 {
                     if (_predicate != null)
                     {
@@ -42,8 +42,7 @@ namespace System.Reactive.Linq.ObservableImpl
                         }
                         catch (Exception exception)
                         {
-                            base._observer.OnError(exception);
-                            base.Dispose();
+                            ForwardOnError(exception);
                             return;
                         }
 
@@ -51,26 +50,14 @@ namespace System.Reactive.Linq.ObservableImpl
                         {
                             _predicate = null;
 
-                            base._observer.OnNext(value);
+                            ForwardOnNext(value);
                         }
                     }
                     else
                     {
-                        base._observer.OnNext(value);
+                        ForwardOnNext(value);
                     }
                 }
-
-                public void OnError(Exception error)
-                {
-                    base._observer.OnError(error);
-                    base.Dispose();
-                }
-
-                public void OnCompleted()
-                {
-                    base._observer.OnCompleted();
-                    base.Dispose();
-                }
             }
         }
 
@@ -89,7 +76,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
             protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-            internal sealed class _ : Sink<TSource>, IObserver<TSource>
+            internal sealed class _ : IdentitySink<TSource>
             {
                 private Func<TSource, int, bool> _predicate;
                 private int _index;
@@ -101,7 +88,7 @@ namespace System.Reactive.Linq.ObservableImpl
                     _index = 0;
                 }
 
-                public void OnNext(TSource value)
+                public override void OnNext(TSource value)
                 {
                     if (_predicate != null)
                     {
@@ -112,8 +99,7 @@ namespace System.Reactive.Linq.ObservableImpl
                         }
                         catch (Exception exception)
                         {
-                            base._observer.OnError(exception);
-                            base.Dispose();
+                            ForwardOnError(exception);
                             return;
                         }
 
@@ -121,26 +107,14 @@ namespace System.Reactive.Linq.ObservableImpl
                         {
                             _predicate = null;
 
-                            base._observer.OnNext(value);
+                            ForwardOnNext(value);
                         }
                     }
                     else
                     {
-                        base._observer.OnNext(value);
+                        ForwardOnNext(value);
                     }
                 }
-
-                public void OnError(Exception error)
-                {
-                    base._observer.OnError(error);
-                    base.Dispose();
-                }
-
-                public void OnCompleted()
-                {
-                    base._observer.OnCompleted();
-                    base.Dispose();
-                }
             }
         }
     }

+ 55 - 129
Rx.NET/Source/src/System.Reactive/Linq/Observable/Sum.cs

@@ -17,7 +17,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
         protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-        internal sealed class _ : Sink<double>, IObserver<double>
+        internal sealed class _ : IdentitySink<double>
         {
             private double _sum;
 
@@ -27,22 +27,15 @@ namespace System.Reactive.Linq.ObservableImpl
                 _sum = 0.0;
             }
 
-            public void OnNext(double value)
+            public override void OnNext(double value)
             {
                 _sum += value;
             }
 
-            public void OnError(Exception error)
+            public override void OnCompleted()
             {
-                base._observer.OnError(error);
-                base.Dispose();
-            }
-
-            public void OnCompleted()
-            {
-                base._observer.OnNext(_sum);
-                base._observer.OnCompleted();
-                base.Dispose();
+                ForwardOnNext(_sum);
+                ForwardOnCompleted();
             }
         }
     }
@@ -60,7 +53,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
         protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-        internal sealed class _ : Sink<float>, IObserver<float>
+        internal sealed class _ : IdentitySink<float>
         {
             private double _sum; // This is what LINQ to Objects does!
 
@@ -70,22 +63,15 @@ namespace System.Reactive.Linq.ObservableImpl
                 _sum = 0.0; // This is what LINQ to Objects does!
             }
 
-            public void OnNext(float value)
+            public override void OnNext(float value)
             {
                 _sum += value; // This is what LINQ to Objects does!
             }
 
-            public void OnError(Exception error)
-            {
-                base._observer.OnError(error);
-                base.Dispose();
-            }
-
-            public void OnCompleted()
+            public override void OnCompleted()
             {
-                base._observer.OnNext((float)_sum); // This is what LINQ to Objects does!
-                base._observer.OnCompleted();
-                base.Dispose();
+                ForwardOnNext((float)_sum); // This is what LINQ to Objects does!
+                ForwardOnCompleted();
             }
         }
     }
@@ -103,7 +89,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
         protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-        internal sealed class _ : Sink<decimal>, IObserver<decimal>
+        internal sealed class _ : IdentitySink<decimal>
         {
             private decimal _sum;
 
@@ -113,22 +99,15 @@ namespace System.Reactive.Linq.ObservableImpl
                 _sum = 0M;
             }
 
-            public void OnNext(decimal value)
+            public override void OnNext(decimal value)
             {
                 _sum += value;
             }
 
-            public void OnError(Exception error)
-            {
-                base._observer.OnError(error);
-                base.Dispose();
-            }
-
-            public void OnCompleted()
+            public override void OnCompleted()
             {
-                base._observer.OnNext(_sum);
-                base._observer.OnCompleted();
-                base.Dispose();
+                ForwardOnNext(_sum);
+                ForwardOnCompleted();
             }
         }
     }
@@ -146,7 +125,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
         protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-        internal sealed class _ : Sink<int>, IObserver<int>
+        internal sealed class _ : IdentitySink<int>
         {
             private int _sum;
 
@@ -156,7 +135,7 @@ namespace System.Reactive.Linq.ObservableImpl
                 _sum = 0;
             }
 
-            public void OnNext(int value)
+            public override void OnNext(int value)
             {
                 try
                 {
@@ -167,22 +146,14 @@ namespace System.Reactive.Linq.ObservableImpl
                 }
                 catch (Exception exception)
                 {
-                    base._observer.OnError(exception);
-                    base.Dispose();
+                    ForwardOnError(exception);
                 }
             }
-
-            public void OnError(Exception error)
-            {
-                base._observer.OnError(error);
-                base.Dispose();
-            }
-
-            public void OnCompleted()
+            
+            public override void OnCompleted()
             {
-                base._observer.OnNext(_sum);
-                base._observer.OnCompleted();
-                base.Dispose();
+                ForwardOnNext(_sum);
+                ForwardOnCompleted();
             }
         }
     }
@@ -200,7 +171,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
         protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-        internal sealed class _ : Sink<long>, IObserver<long>
+        internal sealed class _ : IdentitySink<long>
         {
             private long _sum;
 
@@ -210,7 +181,7 @@ namespace System.Reactive.Linq.ObservableImpl
                 _sum = 0L;
             }
 
-            public void OnNext(long value)
+            public override void OnNext(long value)
             {
                 try
                 {
@@ -221,22 +192,14 @@ namespace System.Reactive.Linq.ObservableImpl
                 }
                 catch (Exception exception)
                 {
-                    base._observer.OnError(exception);
-                    base.Dispose();
+                    ForwardOnError(exception);
                 }
             }
 
-            public void OnError(Exception error)
-            {
-                base._observer.OnError(error);
-                base.Dispose();
-            }
-
-            public void OnCompleted()
+            public override void OnCompleted()
             {
-                base._observer.OnNext(_sum);
-                base._observer.OnCompleted();
-                base.Dispose();
+                ForwardOnNext(_sum);
+                ForwardOnCompleted();
             }
         }
     }
@@ -254,7 +217,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
         protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-        internal sealed class _ : Sink<double?>, IObserver<double?>
+        internal sealed class _ : IdentitySink<double?>
         {
             private double _sum;
 
@@ -264,23 +227,16 @@ namespace System.Reactive.Linq.ObservableImpl
                 _sum = 0.0;
             }
 
-            public void OnNext(double? value)
+            public override void OnNext(double? value)
             {
                 if (value != null)
                     _sum += value.Value;
             }
 
-            public void OnError(Exception error)
+            public override void OnCompleted()
             {
-                base._observer.OnError(error);
-                base.Dispose();
-            }
-
-            public void OnCompleted()
-            {
-                base._observer.OnNext(_sum);
-                base._observer.OnCompleted();
-                base.Dispose();
+                ForwardOnNext(_sum);
+                ForwardOnCompleted();
             }
         }
     }
@@ -298,7 +254,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
         protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-        internal sealed class _ : Sink<float?>, IObserver<float?>
+        internal sealed class _ : IdentitySink<float?>
         {
             private double _sum; // This is what LINQ to Objects does!
 
@@ -308,23 +264,16 @@ namespace System.Reactive.Linq.ObservableImpl
                 _sum = 0.0; // This is what LINQ to Objects does!
             }
 
-            public void OnNext(float? value)
+            public override void OnNext(float? value)
             {
                 if (value != null)
                     _sum += value.Value; // This is what LINQ to Objects does!
             }
 
-            public void OnError(Exception error)
-            {
-                base._observer.OnError(error);
-                base.Dispose();
-            }
-
-            public void OnCompleted()
+            public override void OnCompleted()
             {
-                base._observer.OnNext((float)_sum); // This is what LINQ to Objects does!
-                base._observer.OnCompleted();
-                base.Dispose();
+                ForwardOnNext((float)_sum); // This is what LINQ to Objects does!
+                ForwardOnCompleted();
             }
         }
     }
@@ -342,7 +291,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
         protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-        internal sealed class _ : Sink<decimal?>, IObserver<decimal?>
+        internal sealed class _ : IdentitySink<decimal?>
         {
             private decimal _sum;
 
@@ -352,23 +301,16 @@ namespace System.Reactive.Linq.ObservableImpl
                 _sum = 0M;
             }
 
-            public void OnNext(decimal? value)
+            public override void OnNext(decimal? value)
             {
                 if (value != null)
                     _sum += value.Value;
             }
 
-            public void OnError(Exception error)
+            public override void OnCompleted()
             {
-                base._observer.OnError(error);
-                base.Dispose();
-            }
-
-            public void OnCompleted()
-            {
-                base._observer.OnNext(_sum);
-                base._observer.OnCompleted();
-                base.Dispose();
+                ForwardOnNext(_sum);
+                ForwardOnCompleted();
             }
         }
     }
@@ -386,7 +328,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
         protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-        internal sealed class _ : Sink<int?>, IObserver<int?>
+        internal sealed class _ : IdentitySink<int?>
         {
             private int _sum;
 
@@ -396,7 +338,7 @@ namespace System.Reactive.Linq.ObservableImpl
                 _sum = 0;
             }
 
-            public void OnNext(int? value)
+            public override void OnNext(int? value)
             {
                 try
                 {
@@ -408,22 +350,14 @@ namespace System.Reactive.Linq.ObservableImpl
                 }
                 catch (Exception exception)
                 {
-                    base._observer.OnError(exception);
-                    base.Dispose();
+                    ForwardOnError(exception);
                 }
             }
 
-            public void OnError(Exception error)
-            {
-                base._observer.OnError(error);
-                base.Dispose();
-            }
-
-            public void OnCompleted()
+            public override void OnCompleted()
             {
-                base._observer.OnNext(_sum);
-                base._observer.OnCompleted();
-                base.Dispose();
+                ForwardOnNext(_sum);
+                ForwardOnCompleted();
             }
         }
     }
@@ -441,7 +375,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
         protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-        internal sealed class _ : Sink<long?>, IObserver<long?>
+        internal sealed class _ : IdentitySink<long?>
         {
             private long _sum;
 
@@ -451,7 +385,7 @@ namespace System.Reactive.Linq.ObservableImpl
                 _sum = 0L;
             }
 
-            public void OnNext(long? value)
+            public override void OnNext(long? value)
             {
                 try
                 {
@@ -463,22 +397,14 @@ namespace System.Reactive.Linq.ObservableImpl
                 }
                 catch (Exception exception)
                 {
-                    base._observer.OnError(exception);
-                    base.Dispose();
+                    ForwardOnError(exception);
                 }
             }
 
-            public void OnError(Exception error)
-            {
-                base._observer.OnError(error);
-                base.Dispose();
-            }
-
-            public void OnCompleted()
+            public override void OnCompleted()
             {
-                base._observer.OnNext(_sum);
-                base._observer.OnCompleted();
-                base.Dispose();
+                ForwardOnNext(_sum);
+                ForwardOnCompleted();
             }
         }
     }

+ 9 - 14
Rx.NET/Source/src/System.Reactive/Linq/Observable/Switch.cs

@@ -19,7 +19,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
         protected override IDisposable Run(_ sink) => sink.Run(this);
 
-        internal sealed class _ : Sink<TSource>, IObserver<IObservable<TSource>>
+        internal sealed class _ : Sink<IObservable<TSource>, TSource> 
         {
             private readonly object _gate = new object();
 
@@ -48,7 +48,7 @@ namespace System.Reactive.Linq.ObservableImpl
                 return StableCompositeDisposable.Create(_subscription, _innerSubscription);
             }
 
-            public void OnNext(IObservable<TSource> value)
+            public override void OnNext(IObservable<TSource> value)
             {
                 var id = default(ulong);
                 lock (_gate)
@@ -62,15 +62,13 @@ namespace System.Reactive.Linq.ObservableImpl
                 d.Disposable = value.SubscribeSafe(new InnerObserver(this, id, d));
             }
 
-            public void OnError(Exception error)
+            public override void OnError(Exception error)
             {
                 lock (_gate)
-                    base._observer.OnError(error);
-
-                base.Dispose();
+                    ForwardOnError(error);
             }
 
-            public void OnCompleted()
+            public override void OnCompleted()
             {
                 lock (_gate)
                 {
@@ -79,8 +77,7 @@ namespace System.Reactive.Linq.ObservableImpl
                     _isStopped = true;
                     if (!_hasLatest)
                     {
-                        base._observer.OnCompleted();
-                        base.Dispose();
+                        ForwardOnCompleted();
                     }
                 }
             }
@@ -104,7 +101,7 @@ namespace System.Reactive.Linq.ObservableImpl
                     {
                         if (_parent._latest == _id)
                         {
-                            _parent._observer.OnNext(value);
+                            _parent.ForwardOnNext(value);
                         }
                     }
                 }
@@ -117,8 +114,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
                         if (_parent._latest == _id)
                         {
-                            _parent._observer.OnError(error);
-                            _parent.Dispose();
+                            _parent.ForwardOnError(error);
                         }
                     }
                 }
@@ -135,8 +131,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
                             if (_parent._isStopped)
                             {
-                                _parent._observer.OnCompleted();
-                                _parent.Dispose();
+                                _parent.ForwardOnCompleted();
                             }
                         }
                     }

+ 7 - 9
Rx.NET/Source/src/System.Reactive/Linq/Observable/Synchronize.cs

@@ -24,7 +24,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
         protected override IDisposable Run(_ sink) => _source.Subscribe(sink);
 
-        internal sealed class _ : Sink<TSource>, IObserver<TSource>
+        internal sealed class _ : IdentitySink<TSource>
         {
             private readonly object _gate;
 
@@ -34,29 +34,27 @@ namespace System.Reactive.Linq.ObservableImpl
                 _gate = gate ?? new object();
             }
 
-            public void OnNext(TSource value)
+            public override void OnNext(TSource value)
             {
                 lock (_gate)
                 {
-                    base._observer.OnNext(value);
+                    ForwardOnNext(value);
                 }
             }
 
-            public void OnError(Exception error)
+            public override void OnError(Exception error)
             {
                 lock (_gate)
                 {
-                    base._observer.OnError(error);
-                    base.Dispose();
+                    ForwardOnError(error);
                 }
             }
 
-            public void OnCompleted()
+            public override void OnCompleted()
             {
                 lock (_gate)
                 {
-                    base._observer.OnCompleted();
-                    base.Dispose();
+                    ForwardOnCompleted();
                 }
             }
         }

+ 12 - 28
Rx.NET/Source/src/System.Reactive/Linq/Observable/Take.cs

@@ -39,7 +39,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
             protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-            internal sealed class _ : Sink<TSource>, IObserver<TSource>
+            internal sealed class _ : IdentitySink<TSource>
             {
                 private int _remaining;
 
@@ -49,32 +49,19 @@ namespace System.Reactive.Linq.ObservableImpl
                     _remaining = count;
                 }
 
-                public void OnNext(TSource value)
+                public override void OnNext(TSource value)
                 {
                     if (_remaining > 0)
                     {
                         --_remaining;
-                        base._observer.OnNext(value);
+                        ForwardOnNext(value);
 
                         if (_remaining == 0)
                         {
-                            base._observer.OnCompleted();
-                            base.Dispose();
+                            ForwardOnCompleted();
                         }
                     }
                 }
-
-                public void OnError(Exception error)
-                {
-                    base._observer.OnError(error);
-                    base.Dispose();
-                }
-
-                public void OnCompleted()
-                {
-                    base._observer.OnCompleted();
-                    base.Dispose();
-                }
             }
         }
 
@@ -112,7 +99,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
             protected override IDisposable Run(_ sink) => sink.Run(this);
 
-            internal sealed class _ : Sink<TSource>, IObserver<TSource>
+            internal sealed class _ : IdentitySink<TSource> 
             {
                 public _(IObserver<TSource> observer, IDisposable cancel)
                     : base(observer, cancel)
@@ -134,34 +121,31 @@ namespace System.Reactive.Linq.ObservableImpl
                 {
                     lock (_gate)
                     {
-                        base._observer.OnCompleted();
-                        base.Dispose();
+                        ForwardOnCompleted();
                     }
                 }
 
-                public void OnNext(TSource value)
+                public override void OnNext(TSource value)
                 {
                     lock (_gate)
                     {
-                        base._observer.OnNext(value);
+                        ForwardOnNext(value);
                     }
                 }
 
-                public void OnError(Exception error)
+                public override void OnError(Exception error)
                 {
                     lock (_gate)
                     {
-                        base._observer.OnError(error);
-                        base.Dispose();
+                        ForwardOnError(error);
                     }
                 }
 
-                public void OnCompleted()
+                public override void OnCompleted()
                 {
                     lock (_gate)
                     {
-                        base._observer.OnCompleted();
-                        base.Dispose();
+                        ForwardOnCompleted();
                     }
                 }
             }

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

@@ -27,7 +27,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
             protected override IDisposable Run(_ sink) => sink.Run();
 
-            internal sealed class _ : Sink<TSource>, IObserver<TSource>
+            internal sealed class _ : IdentitySink<TSource>
             {
                 // CONSIDER: This sink has a parent reference that can be considered for removal.
 
@@ -54,20 +54,14 @@ namespace System.Reactive.Linq.ObservableImpl
                     return StableCompositeDisposable.Create(_subscription, _loop);
                 }
 
-                public void OnNext(TSource value)
+                public override void OnNext(TSource value)
                 {
                     _queue.Enqueue(value);
                     if (_queue.Count > _parent._count)
                         _queue.Dequeue();
                 }
 
-                public void OnError(Exception error)
-                {
-                    base._observer.OnError(error);
-                    base.Dispose();
-                }
-
-                public void OnCompleted()
+                public override void OnCompleted()
                 {
                     _subscription.Dispose();
 
@@ -82,13 +76,12 @@ namespace System.Reactive.Linq.ObservableImpl
                 {
                     if (_queue.Count > 0)
                     {
-                        base._observer.OnNext(_queue.Dequeue());
+                        ForwardOnNext(_queue.Dequeue());
                         recurse();
                     }
                     else
                     {
-                        base._observer.OnCompleted();
-                        base.Dispose();
+                        ForwardOnCompleted();
                     }
                 }
 
@@ -100,11 +93,11 @@ namespace System.Reactive.Linq.ObservableImpl
                     {
                         if (n == 0)
                         {
-                            base._observer.OnCompleted();
+                            ForwardOnCompleted();
                             break;
                         }
                         else
-                            base._observer.OnNext(_queue.Dequeue());
+                            ForwardOnNext(_queue.Dequeue());
 
                         n--;
                     }
@@ -133,7 +126,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
             protected override IDisposable Run(_ sink) => sink.Run();
 
-            internal sealed class _ : Sink<TSource>, IObserver<TSource>
+            internal sealed class _ : IdentitySink<TSource>
             {
                 // CONSIDER: This sink has a parent reference that can be considered for removal.
 
@@ -162,20 +155,14 @@ namespace System.Reactive.Linq.ObservableImpl
                     return StableCompositeDisposable.Create(_subscription, _loop);
                 }
 
-                public void OnNext(TSource value)
+                public override void OnNext(TSource value)
                 {
                     var now = _watch.Elapsed;
                     _queue.Enqueue(new System.Reactive.TimeInterval<TSource>(value, now));
                     Trim(now);
                 }
 
-                public void OnError(Exception error)
-                {
-                    base._observer.OnError(error);
-                    base.Dispose();
-                }
-
-                public void OnCompleted()
+                public override void OnCompleted()
                 {
                     _subscription.Dispose();
 
@@ -193,13 +180,12 @@ namespace System.Reactive.Linq.ObservableImpl
                 {
                     if (_queue.Count > 0)
                     {
-                        base._observer.OnNext(_queue.Dequeue().Value);
+                        ForwardOnNext(_queue.Dequeue().Value);
                         recurse();
                     }
                     else
                     {
-                        base._observer.OnCompleted();
-                        base.Dispose();
+                        ForwardOnCompleted();
                     }
                 }
 
@@ -211,11 +197,11 @@ namespace System.Reactive.Linq.ObservableImpl
                     {
                         if (n == 0)
                         {
-                            base._observer.OnCompleted();
+                            ForwardOnCompleted();
                             break;
                         }
                         else
-                            base._observer.OnNext(_queue.Dequeue().Value);
+                            ForwardOnNext(_queue.Dequeue().Value);
 
                         n--;
                     }

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

@@ -24,7 +24,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
             protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-            internal sealed class _ : Sink<IList<TSource>>, IObserver<TSource>
+            internal sealed class _ : Sink<TSource, IList<TSource>> 
             {
                 private readonly int _count;
                 private Queue<TSource> _queue;
@@ -36,28 +36,21 @@ namespace System.Reactive.Linq.ObservableImpl
                     _queue = new Queue<TSource>();
                 }
 
-                public void OnNext(TSource value)
+                public override void OnNext(TSource value)
                 {
                     _queue.Enqueue(value);
                     if (_queue.Count > _count)
                         _queue.Dequeue();
                 }
 
-                public void OnError(Exception error)
-                {
-                    base._observer.OnError(error);
-                    base.Dispose();
-                }
-
-                public void OnCompleted()
+                public override void OnCompleted()
                 {
                     var res = new List<TSource>(_queue.Count);
                     while (_queue.Count > 0)
                         res.Add(_queue.Dequeue());
 
-                    base._observer.OnNext(res);
-                    base._observer.OnCompleted();
-                    base.Dispose();
+                    ForwardOnNext(res);
+                    ForwardOnCompleted();
                 }
             }
         }
@@ -79,7 +72,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
             protected override IDisposable Run(_ sink) => sink.Run(this);
 
-            internal sealed class _ : Sink<IList<TSource>>, IObserver<TSource>
+            internal sealed class _ : Sink<TSource, IList<TSource>> 
             {
                 private readonly TimeSpan _duration;
                 private Queue<System.Reactive.TimeInterval<TSource>> _queue;
@@ -100,20 +93,14 @@ namespace System.Reactive.Linq.ObservableImpl
                     return parent._source.SubscribeSafe(this);
                 }
 
-                public void OnNext(TSource value)
+                public override void OnNext(TSource value)
                 {
                     var now = _watch.Elapsed;
                     _queue.Enqueue(new System.Reactive.TimeInterval<TSource>(value, now));
                     Trim(now);
                 }
 
-                public void OnError(Exception error)
-                {
-                    base._observer.OnError(error);
-                    base.Dispose();
-                }
-
-                public void OnCompleted()
+                public override void OnCompleted()
                 {
                     var now = _watch.Elapsed;
                     Trim(now);
@@ -122,9 +109,8 @@ namespace System.Reactive.Linq.ObservableImpl
                     while (_queue.Count > 0)
                         res.Add(_queue.Dequeue().Value);
 
-                    base._observer.OnNext(res);
-                    base._observer.OnCompleted();
-                    base.Dispose();
+                    ForwardOnNext(res);
+                    ForwardOnCompleted();
                 }
 
                 private void Trim(TimeSpan now)

+ 15 - 22
Rx.NET/Source/src/System.Reactive/Linq/Observable/TakeUntil.cs

@@ -22,7 +22,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
         protected override IDisposable Run(_ sink) => sink.Run(this);
 
-        internal sealed class _ : Sink<TSource>
+        internal sealed class _ : IdentitySink<TSource>
         {
             public _(IObserver<TSource> observer, IDisposable cancel)
                 : base(observer, cancel)
@@ -75,13 +75,13 @@ namespace System.Reactive.Linq.ObservableImpl
                 {
                     if (_open)
                     {
-                        _parent._observer.OnNext(value);
+                        _parent.ForwardOnNext(value);
                     }
                     else
                     {
                         lock (_parent)
                         {
-                            _parent._observer.OnNext(value);
+                            _parent.ForwardOnNext(value);
                         }
                     }
                 }
@@ -90,8 +90,7 @@ namespace System.Reactive.Linq.ObservableImpl
                 {
                     lock (_parent)
                     {
-                        _parent._observer.OnError(error);
-                        _parent.Dispose();
+                        _parent.ForwardOnError(error);
                     }
                 }
 
@@ -99,8 +98,7 @@ namespace System.Reactive.Linq.ObservableImpl
                 {
                     lock (_parent)
                     {
-                        _parent._observer.OnCompleted();
-                        _parent.Dispose();
+                        _parent.ForwardOnCompleted();
                     }
                 }
             }
@@ -127,8 +125,7 @@ namespace System.Reactive.Linq.ObservableImpl
                 {
                     lock (_parent)
                     {
-                        _parent._observer.OnCompleted();
-                        _parent.Dispose();
+                        _parent.ForwardOnCompleted();
                     }
                 }
 
@@ -136,8 +133,7 @@ namespace System.Reactive.Linq.ObservableImpl
                 {
                     lock (_parent)
                     {
-                        _parent._observer.OnError(error);
-                        _parent.Dispose();
+                        _parent.ForwardOnError(error);
                     }
                 }
 
@@ -187,7 +183,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
         protected override IDisposable Run(_ sink) => sink.Run(this);
 
-        internal sealed class _ : Sink<TSource>, IObserver<TSource>
+        internal sealed class _ : IdentitySink<TSource>
         {
             private readonly object _gate = new object();
 
@@ -207,34 +203,31 @@ namespace System.Reactive.Linq.ObservableImpl
             {
                 lock (_gate)
                 {
-                    base._observer.OnCompleted();
-                    base.Dispose();
+                    ForwardOnCompleted();
                 }
             }
 
-            public void OnNext(TSource value)
+            public override void OnNext(TSource value)
             {
                 lock (_gate)
                 {
-                    base._observer.OnNext(value);
+                    ForwardOnNext(value);
                 }
             }
 
-            public void OnError(Exception error)
+            public override void OnError(Exception error)
             {
                 lock (_gate)
                 {
-                    base._observer.OnError(error);
-                    base.Dispose();
+                    ForwardOnError(error);
                 }
             }
 
-            public void OnCompleted()
+            public override void OnCompleted()
             {
                 lock (_gate)
                 {
-                    base._observer.OnCompleted();
-                    base.Dispose();
+                    ForwardOnCompleted();
                 }
             }
         }

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

@@ -21,7 +21,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
             protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-            internal sealed class _ : Sink<TSource>, IObserver<TSource>
+            internal sealed class _ : IdentitySink<TSource>
             {
                 private readonly Func<TSource, bool> _predicate;
                 private bool _running;
@@ -33,7 +33,7 @@ namespace System.Reactive.Linq.ObservableImpl
                     _running = true;
                 }
 
-                public void OnNext(TSource value)
+                public override void OnNext(TSource value)
                 {
                     if (_running)
                     {
@@ -43,34 +43,20 @@ namespace System.Reactive.Linq.ObservableImpl
                         }
                         catch (Exception exception)
                         {
-                            base._observer.OnError(exception);
-                            base.Dispose();
+                            ForwardOnError(exception);
                             return;
                         }
 
                         if (_running)
                         {
-                            base._observer.OnNext(value);
+                            ForwardOnNext(value);
                         }
                         else
                         {
-                            base._observer.OnCompleted();
-                            base.Dispose();
+                            ForwardOnCompleted();
                         }
                     }
                 }
-
-                public void OnError(Exception error)
-                {
-                    base._observer.OnError(error);
-                    base.Dispose();
-                }
-
-                public void OnCompleted()
-                {
-                    base._observer.OnCompleted();
-                    base.Dispose();
-                }
             }
         }
 
@@ -89,7 +75,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
             protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-            internal sealed class _ : Sink<TSource>, IObserver<TSource>
+            internal sealed class _ : IdentitySink<TSource>
             {
                 private readonly Func<TSource, int, bool> _predicate;
                 private bool _running;
@@ -103,7 +89,7 @@ namespace System.Reactive.Linq.ObservableImpl
                     _index = 0;
                 }
 
-                public void OnNext(TSource value)
+                public override void OnNext(TSource value)
                 {
                     if (_running)
                     {
@@ -113,34 +99,20 @@ namespace System.Reactive.Linq.ObservableImpl
                         }
                         catch (Exception exception)
                         {
-                            base._observer.OnError(exception);
-                            base.Dispose();
+                            ForwardOnError(exception);
                             return;
                         }
 
                         if (_running)
                         {
-                            base._observer.OnNext(value);
+                            ForwardOnNext(value);
                         }
                         else
                         {
-                            base._observer.OnCompleted();
-                            base.Dispose();
+                            ForwardOnCompleted();
                         }
                     }
                 }
-
-                public void OnError(Exception error)
-                {
-                    base._observer.OnError(error);
-                    base.Dispose();
-                }
-
-                public void OnCompleted()
-                {
-                    base._observer.OnCompleted();
-                    base.Dispose();
-                }
             }
         }
     }

+ 20 - 26
Rx.NET/Source/src/System.Reactive/Linq/Observable/Throttle.cs

@@ -24,7 +24,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
         protected override IDisposable Run(_ sink) => sink.Run(_source);
 
-        internal sealed class _ : Sink<TSource>, IObserver<TSource>
+        internal sealed class _ : IdentitySink<TSource>
         {
             private readonly TimeSpan _dueTime;
             private readonly IScheduler _scheduler;
@@ -55,7 +55,7 @@ namespace System.Reactive.Linq.ObservableImpl
                 return StableCompositeDisposable.Create(subscription, _cancelable);
             }
 
-            public void OnNext(TSource value)
+            public override void OnNext(TSource value)
             {
                 var currentid = default(ulong);
                 lock (_gate)
@@ -75,38 +75,36 @@ namespace System.Reactive.Linq.ObservableImpl
                 lock (_gate)
                 {
                     if (_hasValue && _id == currentid)
-                        base._observer.OnNext(_value);
+                        ForwardOnNext(_value);
                     _hasValue = false;
                 }
 
                 return Disposable.Empty;
             }
 
-            public void OnError(Exception error)
+            public override void OnError(Exception error)
             {
                 _cancelable.Dispose();
 
                 lock (_gate)
                 {
-                    base._observer.OnError(error);
-                    base.Dispose();
+                    ForwardOnError(error);
 
                     _hasValue = false;
                     _id = unchecked(_id + 1);
                 }
             }
-
-            public void OnCompleted()
+            
+            public override void OnCompleted()
             {
                 _cancelable.Dispose();
 
                 lock (_gate)
                 {
                     if (_hasValue)
-                        base._observer.OnNext(_value);
+                        ForwardOnNext(_value);
 
-                    base._observer.OnCompleted();
-                    base.Dispose();
+                    ForwardOnCompleted();
 
                     _hasValue = false;
                     _id = unchecked(_id + 1);
@@ -130,7 +128,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
         protected override IDisposable Run(_ sink) => sink.Run(this);
 
-        internal sealed class _ : Sink<TSource>, IObserver<TSource>
+        internal sealed class _ : IdentitySink<TSource>
         {
             private readonly Func<TSource, IObservable<TThrottle>> _throttleSelector;
 
@@ -159,7 +157,7 @@ namespace System.Reactive.Linq.ObservableImpl
                 return StableCompositeDisposable.Create(subscription, _cancelable);
             }
 
-            public void OnNext(TSource value)
+            public override void OnNext(TSource value)
             {
                 var throttle = default(IObservable<TThrottle>);
                 try
@@ -170,8 +168,7 @@ namespace System.Reactive.Linq.ObservableImpl
                 {
                     lock (_gate)
                     {
-                        base._observer.OnError(error);
-                        base.Dispose();
+                        ForwardOnError(error);
                     }
 
                     return;
@@ -191,31 +188,29 @@ namespace System.Reactive.Linq.ObservableImpl
                 d.Disposable = throttle.SubscribeSafe(new ThrottleObserver(this, value, currentid, d));
             }
 
-            public void OnError(Exception error)
+            public override void OnError(Exception error)
             {
                 _cancelable.Dispose();
 
                 lock (_gate)
                 {
-                    base._observer.OnError(error);
-                    base.Dispose();
+                    ForwardOnError(error);
 
                     _hasValue = false;
                     _id = unchecked(_id + 1);
                 }
             }
 
-            public void OnCompleted()
+            public override void OnCompleted()
             {
                 _cancelable.Dispose();
 
                 lock (_gate)
                 {
                     if (_hasValue)
-                        base._observer.OnNext(_value);
+                        ForwardOnNext(_value);
 
-                    base._observer.OnCompleted();
-                    base.Dispose();
+                    ForwardOnCompleted();
 
                     _hasValue = false;
                     _id = unchecked(_id + 1);
@@ -242,7 +237,7 @@ namespace System.Reactive.Linq.ObservableImpl
                     lock (_parent._gate)
                     {
                         if (_parent._hasValue && _parent._id == _currentid)
-                            _parent._observer.OnNext(_value);
+                            _parent.ForwardOnNext(_value);
 
                         _parent._hasValue = false;
                         _self.Dispose();
@@ -253,8 +248,7 @@ namespace System.Reactive.Linq.ObservableImpl
                 {
                     lock (_parent._gate)
                     {
-                        _parent._observer.OnError(error);
-                        _parent.Dispose();
+                        _parent.ForwardOnError(error);
                     }
                 }
 
@@ -263,7 +257,7 @@ namespace System.Reactive.Linq.ObservableImpl
                     lock (_parent._gate)
                     {
                         if (_parent._hasValue && _parent._id == _currentid)
-                            _parent._observer.OnNext(_value);
+                            _parent.ForwardOnNext(_value);
 
                         _parent._hasValue = false;
                         _self.Dispose();

+ 2 - 3
Rx.NET/Source/src/System.Reactive/Linq/Observable/Throw.cs

@@ -21,7 +21,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
         protected override IDisposable Run(_ sink) => sink.Run(_scheduler);
 
-        internal sealed class _ : Sink<TResult>
+        internal sealed class _ : IdentitySink<TResult>
         {
             private readonly Exception _exception;
 
@@ -38,8 +38,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
             private void Invoke()
             {
-                base._observer.OnError(_exception);
-                base.Dispose();
+                ForwardOnError(_exception);
             }
         }
     }

+ 3 - 15
Rx.NET/Source/src/System.Reactive/Linq/Observable/TimeInterval.cs

@@ -21,7 +21,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
         protected override IDisposable Run(_ sink) => sink.Run(this);
 
-        internal sealed class _ : Sink<System.Reactive.TimeInterval<TSource>>, IObserver<TSource>
+        internal sealed class _ : Sink<TSource, System.Reactive.TimeInterval<TSource>> 
         {
             public _(IObserver<System.Reactive.TimeInterval<TSource>> observer, IDisposable cancel)
                 : base(observer, cancel)
@@ -39,24 +39,12 @@ namespace System.Reactive.Linq.ObservableImpl
                 return parent._source.Subscribe(this);
             }
 
-            public void OnNext(TSource value)
+            public override void OnNext(TSource value)
             {
                 var now = _watch.Elapsed;
                 var span = now.Subtract(_last);
                 _last = now;
-                base._observer.OnNext(new System.Reactive.TimeInterval<TSource>(value, span));
-            }
-
-            public void OnError(Exception error)
-            {
-                base._observer.OnError(error);
-                Dispose();
-            }
-
-            public void OnCompleted()
-            {
-                base._observer.OnCompleted();
-                Dispose();
+                ForwardOnNext(new System.Reactive.TimeInterval<TSource>(value, span));
             }
         }
     }

+ 23 - 31
Rx.NET/Source/src/System.Reactive/Linq/Observable/Timeout.cs

@@ -28,7 +28,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
             protected override IDisposable Run(_ sink) => sink.Run(_source);
 
-            internal sealed class _ : Sink<TSource>, IObserver<TSource>
+            internal sealed class _ : IdentitySink<TSource>
             {
                 private readonly TimeSpan _dueTime;
                 private readonly IObservable<TSource> _other;
@@ -86,7 +86,7 @@ namespace System.Reactive.Linq.ObservableImpl
                     return Disposable.Empty;
                 }
 
-                public void OnNext(TSource value)
+                public override void OnNext(TSource value)
                 {
                     var onNextWins = false;
 
@@ -101,12 +101,12 @@ namespace System.Reactive.Linq.ObservableImpl
 
                     if (onNextWins)
                     {
-                        base._observer.OnNext(value);
+                        ForwardOnNext(value);
                         CreateTimer();
                     }
                 }
 
-                public void OnError(Exception error)
+                public override void OnError(Exception error)
                 {
                     var onErrorWins = false;
 
@@ -121,12 +121,11 @@ namespace System.Reactive.Linq.ObservableImpl
 
                     if (onErrorWins)
                     {
-                        base._observer.OnError(error);
-                        base.Dispose();
+                        ForwardOnError(error);
                     }
                 }
 
-                public void OnCompleted()
+                public override void OnCompleted()
                 {
                     var onCompletedWins = false;
 
@@ -141,8 +140,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
                     if (onCompletedWins)
                     {
-                        base._observer.OnCompleted();
-                        base.Dispose();
+                        ForwardOnCompleted();
                     }
                 }
             }
@@ -167,7 +165,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
             protected override IDisposable Run(_ sink) => sink.Run(this);
 
-            internal sealed class _ : Sink<TSource>, IObserver<TSource>
+            internal sealed class _ : IdentitySink<TSource>
             {
                 private readonly IObservable<TSource> _other;
 
@@ -211,16 +209,16 @@ namespace System.Reactive.Linq.ObservableImpl
                         _subscription.Disposable = _other.SubscribeSafe(GetForwarder());
                 }
 
-                public void OnNext(TSource value)
+                public override void OnNext(TSource value)
                 {
                     lock (_gate)
                     {
                         if (!_switched)
-                            base._observer.OnNext(value);
+                            ForwardOnNext(value);
                     }
                 }
 
-                public void OnError(Exception error)
+                public override void OnError(Exception error)
                 {
                     var onErrorWins = false;
 
@@ -232,12 +230,11 @@ namespace System.Reactive.Linq.ObservableImpl
 
                     if (onErrorWins)
                     {
-                        base._observer.OnError(error);
-                        base.Dispose();
+                        ForwardOnError(error);
                     }
                 }
 
-                public void OnCompleted()
+                public override void OnCompleted()
                 {
                     var onCompletedWins = false;
 
@@ -249,8 +246,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
                     if (onCompletedWins)
                     {
-                        base._observer.OnCompleted();
-                        base.Dispose();
+                        ForwardOnCompleted();
                     }
                 }
             }
@@ -276,7 +272,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
         protected override IDisposable Run(_ sink) => sink.Run(this);
 
-        internal sealed class _ : Sink<TSource>, IObserver<TSource>
+        internal sealed class _ : IdentitySink<TSource>
         {
             private readonly Func<TSource, IObservable<TTimeout>> _timeoutSelector;
             private readonly IObservable<TSource> _other;
@@ -311,11 +307,11 @@ namespace System.Reactive.Linq.ObservableImpl
                 return StableCompositeDisposable.Create(_subscription, _timer);
             }
 
-            public void OnNext(TSource value)
+            public override void OnNext(TSource value)
             {
                 if (ObserverWins())
                 {
-                    base._observer.OnNext(value);
+                    ForwardOnNext(value);
 
                     var timeout = default(IObservable<TTimeout>);
                     try
@@ -324,8 +320,7 @@ namespace System.Reactive.Linq.ObservableImpl
                     }
                     catch (Exception error)
                     {
-                        base._observer.OnError(error);
-                        base.Dispose();
+                        ForwardOnError(error);
                         return;
                     }
 
@@ -333,21 +328,19 @@ namespace System.Reactive.Linq.ObservableImpl
                 }
             }
 
-            public void OnError(Exception error)
+            public override void OnError(Exception error)
             {
                 if (ObserverWins())
                 {
-                    base._observer.OnError(error);
-                    base.Dispose();
+                    ForwardOnError(error);
                 }
             }
 
-            public void OnCompleted()
+            public override void OnCompleted()
             {
                 if (ObserverWins())
                 {
-                    base._observer.OnCompleted();
-                    base.Dispose();
+                    ForwardOnCompleted();
                 }
             }
 
@@ -385,8 +378,7 @@ namespace System.Reactive.Linq.ObservableImpl
                 {
                     if (TimerWins())
                     {
-                        _parent._observer.OnError(error);
-                        _parent.Dispose();
+                        _parent.ForwardOnError(error);
                     }
                 }
 

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

@@ -49,7 +49,7 @@ namespace System.Reactive.Linq.ObservableImpl
                 protected override IDisposable Run(_ sink) => sink.Run(this, _dueTime);
             }
 
-            internal sealed class _ : Sink<long>
+            internal sealed class _ : IdentitySink<long>
             {
                 public _(IObserver<long> observer, IDisposable cancel)
                     : base(observer, cancel)
@@ -68,9 +68,8 @@ namespace System.Reactive.Linq.ObservableImpl
 
                 private void Invoke()
                 {
-                    base._observer.OnNext(0);
-                    base._observer.OnCompleted();
-                    base.Dispose();
+                    ForwardOnNext(0);
+                    ForwardOnCompleted();
                 }
             }
         }
@@ -116,7 +115,7 @@ namespace System.Reactive.Linq.ObservableImpl
                 protected override IDisposable Run(_ sink) => sink.Run(this, _dueTime);
             }
 
-            internal sealed class _ : Sink<long>
+            internal sealed class _ : IdentitySink<long>
             {
                 private readonly TimeSpan _period;
 
@@ -160,7 +159,7 @@ namespace System.Reactive.Linq.ObservableImpl
                 //
                 private long Tick(long count)
                 {
-                    base._observer.OnNext(count);
+                    ForwardOnNext(count);
                     return unchecked(count + 1);
                 }
 
@@ -224,7 +223,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
                     try
                     {
-                        base._observer.OnNext(0L);
+                        ForwardOnNext(0L);
                     }
                     catch (Exception e)
                     {
@@ -263,7 +262,7 @@ namespace System.Reactive.Linq.ObservableImpl
                     //
                     if (Interlocked.Increment(ref _pendingTickCount) == 1)
                     {
-                        base._observer.OnNext(count);
+                        ForwardOnNext(count);
                         Interlocked.Decrement(ref _pendingTickCount);
                     }
 
@@ -274,7 +273,7 @@ namespace System.Reactive.Linq.ObservableImpl
                 {
                     try
                     {
-                        base._observer.OnNext(count);
+                        ForwardOnNext(count);
                     }
                     catch (Exception e)
                     {

+ 3 - 15
Rx.NET/Source/src/System.Reactive/Linq/Observable/Timestamp.cs

@@ -21,7 +21,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
         protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-        internal sealed class _ : Sink<Timestamped<TSource>>, IObserver<TSource>
+        internal sealed class _ : Sink<TSource, Timestamped<TSource>> 
         {
             private readonly IScheduler _scheduler;
 
@@ -31,21 +31,9 @@ namespace System.Reactive.Linq.ObservableImpl
                 _scheduler = scheduler;
             }
 
-            public void OnNext(TSource value)
+            public override void OnNext(TSource value)
             {
-                base._observer.OnNext(new Timestamped<TSource>(value, _scheduler.Now));
-            }
-
-            public void OnError(Exception error)
-            {
-                base._observer.OnError(error);
-                base.Dispose();
-            }
-
-            public void OnCompleted()
-            {
-                base._observer.OnCompleted();
-                base.Dispose();
+                ForwardOnNext(new Timestamped<TSource>(value, _scheduler.Now));
             }
         }
     }

+ 5 - 12
Rx.NET/Source/src/System.Reactive/Linq/Observable/ToArray.cs

@@ -19,7 +19,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
         protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-        internal sealed class _ : Sink<TSource[]>, IObserver<TSource>
+        internal sealed class _ : Sink<TSource, TSource[]> 
         {
             private readonly List<TSource> _list;
 
@@ -29,22 +29,15 @@ namespace System.Reactive.Linq.ObservableImpl
                 _list = new List<TSource>();
             }
 
-            public void OnNext(TSource value)
+            public override void OnNext(TSource value)
             {
                 _list.Add(value);
             }
 
-            public void OnError(Exception error)
+            public override void OnCompleted()
             {
-                base._observer.OnError(error);
-                base.Dispose();
-            }
-
-            public void OnCompleted()
-            {
-                base._observer.OnNext(_list.ToArray());
-                base._observer.OnCompleted();
-                base.Dispose();
+                ForwardOnNext(_list.ToArray());
+                ForwardOnCompleted();
             }
         }
     }

+ 6 - 14
Rx.NET/Source/src/System.Reactive/Linq/Observable/ToDictionary.cs

@@ -25,7 +25,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
         protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-        internal sealed class _ : Sink<IDictionary<TKey, TElement>>, IObserver<TSource>
+        internal sealed class _ : Sink<TSource, IDictionary<TKey, TElement>> 
         {
             private readonly Func<TSource, TKey> _keySelector;
             private readonly Func<TSource, TElement> _elementSelector;
@@ -39,7 +39,7 @@ namespace System.Reactive.Linq.ObservableImpl
                 _dictionary = new Dictionary<TKey, TElement>(parent._comparer);
             }
 
-            public void OnNext(TSource value)
+            public override void OnNext(TSource value)
             {
                 try
                 {
@@ -47,22 +47,14 @@ namespace System.Reactive.Linq.ObservableImpl
                 }
                 catch (Exception ex)
                 {
-                    base._observer.OnError(ex);
-                    base.Dispose();
+                    ForwardOnError(ex);
                 }
             }
 
-            public void OnError(Exception error)
+            public override void OnCompleted()
             {
-                base._observer.OnError(error);
-                base.Dispose();
-            }
-
-            public void OnCompleted()
-            {
-                base._observer.OnNext(_dictionary);
-                base._observer.OnCompleted();
-                base.Dispose();
+                ForwardOnNext(_dictionary);
+                ForwardOnCompleted();
             }
         }
     }

+ 5 - 12
Rx.NET/Source/src/System.Reactive/Linq/Observable/ToList.cs

@@ -19,7 +19,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
         protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-        internal sealed class _ : Sink<IList<TSource>>, IObserver<TSource>
+        internal sealed class _ : Sink<TSource, IList<TSource>> 
         {
             private readonly List<TSource> _list;
 
@@ -29,22 +29,15 @@ namespace System.Reactive.Linq.ObservableImpl
                 _list = new List<TSource>();
             }
 
-            public void OnNext(TSource value)
+            public override void OnNext(TSource value)
             {
                 _list.Add(value);
             }
 
-            public void OnError(Exception error)
+            public override void OnCompleted()
             {
-                base._observer.OnError(error);
-                base.Dispose();
-            }
-
-            public void OnCompleted()
-            {
-                base._observer.OnNext(_list);
-                base._observer.OnCompleted();
-                base.Dispose();
+                ForwardOnNext(_list);
+                ForwardOnCompleted();
             }
         }
     }

+ 6 - 14
Rx.NET/Source/src/System.Reactive/Linq/Observable/ToLookup.cs

@@ -26,7 +26,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
         protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-        internal sealed class _ : Sink<ILookup<TKey, TElement>>, IObserver<TSource>
+        internal sealed class _ : Sink<TSource, ILookup<TKey, TElement>> 
         {
             private readonly Func<TSource, TKey> _keySelector;
             private readonly Func<TSource, TElement> _elementSelector;
@@ -40,7 +40,7 @@ namespace System.Reactive.Linq.ObservableImpl
                 _lookup = new Lookup<TKey, TElement>(parent._comparer);
             }
 
-            public void OnNext(TSource value)
+            public override void OnNext(TSource value)
             {
                 try
                 {
@@ -48,22 +48,14 @@ namespace System.Reactive.Linq.ObservableImpl
                 }
                 catch (Exception ex)
                 {
-                    base._observer.OnError(ex);
-                    base.Dispose();
+                    ForwardOnError(ex);
                 }
             }
 
-            public void OnError(Exception error)
+            public override void OnCompleted()
             {
-                base._observer.OnError(error);
-                base.Dispose();
-            }
-
-            public void OnCompleted()
-            {
-                base._observer.OnNext(_lookup);
-                base._observer.OnCompleted();
-                base.Dispose();
+                ForwardOnNext(_lookup);
+                ForwardOnCompleted();
             }
         }
     }

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

@@ -23,7 +23,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
         protected override IDisposable Run(_ sink) => sink.Run(this);
 
-        internal sealed class _ : Sink<TSource>
+        internal sealed class _ : IdentitySink<TSource>
         {
             public _(IObserver<TSource> observer, IDisposable cancel)
                 : base(observer, cancel)
@@ -39,8 +39,7 @@ namespace System.Reactive.Linq.ObservableImpl
                 }
                 catch (Exception exception)
                 {
-                    base._observer.OnError(exception);
-                    base.Dispose();
+                    ForwardOnError(exception);
                     return Disposable.Empty;
                 }
 
@@ -107,8 +106,7 @@ namespace System.Reactive.Linq.ObservableImpl
                 {
                     state.enumerator.Dispose();
 
-                    base._observer.OnError(ex);
-                    base.Dispose();
+                    ForwardOnError(ex);
                     return;
                 }
 
@@ -116,12 +114,11 @@ namespace System.Reactive.Linq.ObservableImpl
                 {
                     state.enumerator.Dispose();
 
-                    base._observer.OnCompleted();
-                    base.Dispose();
+                    ForwardOnCompleted();
                     return;
                 }
 
-                base._observer.OnNext(current);
+                ForwardOnNext(current);
                 recurse(state);
             }
 
@@ -146,17 +143,17 @@ namespace System.Reactive.Linq.ObservableImpl
 
                     if (ex != null)
                     {
-                        base._observer.OnError(ex);
+                        ForwardOnError(ex);
                         break;
                     }
 
                     if (!hasNext)
                     {
-                        base._observer.OnCompleted();
+                        ForwardOnCompleted();
                         break;
                     }
 
-                    base._observer.OnNext(current);
+                    ForwardOnNext(current);
                 }
 
                 enumerator.Dispose();

+ 1 - 18
Rx.NET/Source/src/System.Reactive/Linq/Observable/Using.cs

@@ -22,7 +22,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
         protected override IDisposable Run(_ sink) => sink.Run(this);
 
-        internal sealed class _ : Sink<TSource>, IObserver<TSource>
+        internal sealed class _ : IdentitySink<TSource>
         {
             public _(IObserver<TSource> observer, IDisposable cancel)
                 : base(observer, cancel)
@@ -47,23 +47,6 @@ namespace System.Reactive.Linq.ObservableImpl
 
                 return StableCompositeDisposable.Create(source.SubscribeSafe(this), disposable);
             }
-
-            public void OnNext(TSource value)
-            {
-                base._observer.OnNext(value);
-            }
-
-            public void OnError(Exception error)
-            {
-                base._observer.OnError(error);
-                base.Dispose();
-            }
-
-            public void OnCompleted()
-            {
-                base._observer.OnCompleted();
-                base.Dispose();
-            }
         }
     }
 }

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

@@ -26,7 +26,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
             protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-            internal sealed class _ : Sink<TSource>, IObserver<TSource>
+            internal sealed class _ : IdentitySink<TSource>
             {
                 private readonly Func<TSource, bool> _predicate;
 
@@ -36,7 +36,7 @@ namespace System.Reactive.Linq.ObservableImpl
                     _predicate = predicate;
                 }
 
-                public void OnNext(TSource value)
+                public override void OnNext(TSource value)
                 {
                     var shouldRun = default(bool);
                     try
@@ -45,28 +45,15 @@ namespace System.Reactive.Linq.ObservableImpl
                     }
                     catch (Exception exception)
                     {
-                        base._observer.OnError(exception);
-                        base.Dispose();
+                        ForwardOnError(exception);
                         return;
                     }
 
                     if (shouldRun)
                     {
-                        base._observer.OnNext(value);
+                        ForwardOnNext(value);
                     }
                 }
-
-                public void OnError(Exception error)
-                {
-                    base._observer.OnError(error);
-                    base.Dispose();
-                }
-
-                public void OnCompleted()
-                {
-                    base._observer.OnCompleted();
-                    base.Dispose();
-                }
             }
         }
 
@@ -85,7 +72,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
             protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-            internal sealed class _ : Sink<TSource>, IObserver<TSource>
+            internal sealed class _ : IdentitySink<TSource>
             {
                 private readonly Func<TSource, int, bool> _predicate;
                 private int _index;
@@ -97,7 +84,7 @@ namespace System.Reactive.Linq.ObservableImpl
                     _index = 0;
                 }
 
-                public void OnNext(TSource value)
+                public override void OnNext(TSource value)
                 {
                     var shouldRun = default(bool);
                     try
@@ -106,28 +93,14 @@ namespace System.Reactive.Linq.ObservableImpl
                     }
                     catch (Exception exception)
                     {
-                        base._observer.OnError(exception);
-                        base.Dispose();
-                        return;
+                        ForwardOnError(exception);
                     }
 
                     if (shouldRun)
                     {
-                        base._observer.OnNext(value);
+                        ForwardOnNext(value);
                     }
                 }
-
-                public void OnError(Exception error)
-                {
-                    base._observer.OnError(error);
-                    base.Dispose();
-                }
-
-                public void OnCompleted()
-                {
-                    base._observer.OnCompleted();
-                    base.Dispose();
-                }
             }
         }
     }

+ 0 - 11
Rx.NET/Source/src/System.Reactive/Linq/Observable/While.cs

@@ -33,17 +33,6 @@ namespace System.Reactive.Linq.ObservableImpl
                 : base(observer, cancel)
             {
             }
-
-            public override void OnNext(TSource value)
-            {
-                base._observer.OnNext(value);
-            }
-
-            public override void OnError(Exception error)
-            {
-                base._observer.OnError(error);
-                base.Dispose();
-            }
         }
     }
 }

+ 48 - 61
Rx.NET/Source/src/System.Reactive/Linq/Observable/Window.cs

@@ -28,7 +28,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
             protected override IDisposable Run(_ sink) => sink.Run(_source);
 
-            internal sealed class _ : Sink<IObservable<TSource>>, IObserver<TSource>
+            internal sealed class _ : Sink<TSource, IObservable<TSource> > 
             {
                 private readonly Queue<ISubject<TSource>> _queue = new Queue<ISubject<TSource>>();
                 private readonly SingleAssignmentDisposable _m = new SingleAssignmentDisposable();
@@ -53,7 +53,7 @@ namespace System.Reactive.Linq.ObservableImpl
                     _n = 0;
 
                     var firstWindow = CreateWindow();
-                    base._observer.OnNext(firstWindow);
+                    ForwardOnNext(firstWindow);
 
                     _m.Disposable = source.SubscribeSafe(this);
 
@@ -67,7 +67,7 @@ namespace System.Reactive.Linq.ObservableImpl
                     return new WindowObservable<TSource>(s, _refCountDisposable);
                 }
 
-                public void OnNext(TSource value)
+                public override void OnNext(TSource value)
                 {
                     foreach (var s in _queue)
                         s.OnNext(value);
@@ -83,26 +83,24 @@ namespace System.Reactive.Linq.ObservableImpl
                     if (_n % _skip == 0)
                     {
                         var newWindow = CreateWindow();
-                        base._observer.OnNext(newWindow);
+                        ForwardOnNext(newWindow);
                     }
                 }
 
-                public void OnError(Exception error)
+                public override void OnError(Exception error)
                 {
                     while (_queue.Count > 0)
                         _queue.Dequeue().OnError(error);
 
-                    base._observer.OnError(error);
-                    base.Dispose();
+                    ForwardOnError(error);
                 }
 
-                public void OnCompleted()
+                public override void OnCompleted()
                 {
                     while (_queue.Count > 0)
                         _queue.Dequeue().OnCompleted();
 
-                    base._observer.OnCompleted();
-                    base.Dispose();
+                    ForwardOnCompleted();
                 }
             }
         }
@@ -126,7 +124,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
             protected override IDisposable Run(_ sink) => sink.Run(this);
 
-            internal sealed class _ : Sink<IObservable<TSource>>, IObserver<TSource>
+            internal sealed class _ : Sink<TSource, IObservable<TSource>> 
             {
                 private readonly object _gate = new object();
                 private readonly Queue<ISubject<TSource>> _q = new Queue<ISubject<TSource>>();
@@ -168,7 +166,7 @@ namespace System.Reactive.Linq.ObservableImpl
                 {
                     var s = new Subject<TSource>();
                     _q.Enqueue(s);
-                    base._observer.OnNext(new WindowObservable<TSource>(s, _refCountDisposable));
+                    ForwardOnNext(new WindowObservable<TSource>(s, _refCountDisposable));
                 }
 
                 private void CreateTimer()
@@ -233,7 +231,7 @@ namespace System.Reactive.Linq.ObservableImpl
                     return Disposable.Empty;
                 }
 
-                public void OnNext(TSource value)
+                public override void OnNext(TSource value)
                 {
                     lock (_gate)
                     {
@@ -242,27 +240,25 @@ namespace System.Reactive.Linq.ObservableImpl
                     }
                 }
 
-                public void OnError(Exception error)
+                public override void OnError(Exception error)
                 {
                     lock (_gate)
                     {
                         foreach (var s in _q)
                             s.OnError(error);
 
-                        base._observer.OnError(error);
-                        base.Dispose();
+                        ForwardOnError(error);
                     }
                 }
 
-                public void OnCompleted()
+                public override void OnCompleted()
                 {
                     lock (_gate)
                     {
                         foreach (var s in _q)
                             s.OnCompleted();
 
-                        base._observer.OnCompleted();
-                        base.Dispose();
+                        ForwardOnCompleted();
                     }
                 }
             }
@@ -285,7 +281,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
             protected override IDisposable Run(_ sink) => sink.Run(this);
 
-            internal sealed class _ : Sink<IObservable<TSource>>, IObserver<TSource>
+            internal sealed class _ : Sink<TSource, IObservable<TSource>> 
             {
                 private readonly object _gate = new object();
 
@@ -322,10 +318,10 @@ namespace System.Reactive.Linq.ObservableImpl
                 private void CreateWindow()
                 {
                     _subject = new Subject<TSource>();
-                    base._observer.OnNext(new WindowObservable<TSource>(_subject, _refCountDisposable));
+                    ForwardOnNext(new WindowObservable<TSource>(_subject, _refCountDisposable));
                 }
 
-                public void OnNext(TSource value)
+                public override void OnNext(TSource value)
                 {
                     lock (_gate)
                     {
@@ -333,25 +329,23 @@ namespace System.Reactive.Linq.ObservableImpl
                     }
                 }
 
-                public void OnError(Exception error)
+                public override void OnError(Exception error)
                 {
                     lock (_gate)
                     {
                         _subject.OnError(error);
 
-                        base._observer.OnError(error);
-                        base.Dispose();
+                        ForwardOnError(error);
                     }
                 }
 
-                public void OnCompleted()
+                public override void OnCompleted()
                 {
                     lock (_gate)
                     {
                         _subject.OnCompleted();
 
-                        base._observer.OnCompleted();
-                        base.Dispose();
+                        ForwardOnCompleted();
                     }
                 }
             }
@@ -376,7 +370,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
             protected override IDisposable Run(_ sink) => sink.Run(_source);
 
-            internal sealed class _ : Sink<IObservable<TSource>>, IObserver<TSource>
+            internal sealed class _ : Sink<TSource, IObservable<TSource>> 
             {
                 private readonly object _gate = new object();
                 private readonly SerialDisposable _timerD = new SerialDisposable();
@@ -406,7 +400,7 @@ namespace System.Reactive.Linq.ObservableImpl
                     _refCountDisposable = new RefCountDisposable(groupDisposable);
 
                     _s = new Subject<TSource>();
-                    base._observer.OnNext(new WindowObservable<TSource>(_s, _refCountDisposable));
+                    ForwardOnNext(new WindowObservable<TSource>(_s, _refCountDisposable));
                     CreateTimer(_s);
 
                     groupDisposable.Add(source.SubscribeSafe(this));
@@ -437,7 +431,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
                         _s.OnCompleted();
                         _s = newWindow;
-                        base._observer.OnNext(new WindowObservable<TSource>(_s, _refCountDisposable));
+                        ForwardOnNext(new WindowObservable<TSource>(_s, _refCountDisposable));
                     }
 
                     CreateTimer(newWindow);
@@ -445,7 +439,7 @@ namespace System.Reactive.Linq.ObservableImpl
                     return d;
                 }
 
-                public void OnNext(TSource value)
+                public override void OnNext(TSource value)
                 {
                     var newWindow = default(Subject<TSource>);
 
@@ -461,7 +455,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
                             _s.OnCompleted();
                             _s = newWindow;
-                            base._observer.OnNext(new WindowObservable<TSource>(_s, _refCountDisposable));
+                            ForwardOnNext(new WindowObservable<TSource>(_s, _refCountDisposable));
                         }
                     }
 
@@ -469,23 +463,21 @@ namespace System.Reactive.Linq.ObservableImpl
                         CreateTimer(newWindow);
                 }
 
-                public void OnError(Exception error)
+                public override void OnError(Exception error)
                 {
                     lock (_gate)
                     {
                         _s.OnError(error);
-                        base._observer.OnError(error);
-                        base.Dispose();
+                        ForwardOnError(error);
                     }
                 }
 
-                public void OnCompleted()
+                public override void OnCompleted()
                 {
                     lock (_gate)
                     {
                         _s.OnCompleted();
-                        base._observer.OnCompleted();
-                        base.Dispose();
+                        ForwardOnCompleted();
                     }
                 }
             }
@@ -509,7 +501,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
             protected override IDisposable Run(_ sink) => sink.Run(_source);
 
-            internal sealed class _ : Sink<IObservable<TSource>>, IObserver<TSource>
+            internal sealed class _ : Sink<TSource, IObservable<TSource>> 
             {
                 private readonly object _gate = new object();
                 private readonly AsyncLock _windowGate = new AsyncLock();
@@ -534,7 +526,7 @@ namespace System.Reactive.Linq.ObservableImpl
                     _refCountDisposable = new RefCountDisposable(groupDisposable);
 
                     var window = new WindowObservable<TSource>(_window, _refCountDisposable);
-                    base._observer.OnNext(window);
+                    ForwardOnNext(window);
 
                     groupDisposable.Add(source.SubscribeSafe(this));
 
@@ -554,8 +546,7 @@ namespace System.Reactive.Linq.ObservableImpl
                     {
                         lock (_gate)
                         {
-                            base._observer.OnError(exception);
-                            base.Dispose();
+                            ForwardOnError(exception);
                         }
                         return;
                     }
@@ -575,7 +566,7 @@ namespace System.Reactive.Linq.ObservableImpl
                         _window = new Subject<TSource>();
 
                         var window = new WindowObservable<TSource>(_window, _refCountDisposable);
-                        base._observer.OnNext(window);
+                        ForwardOnNext(window);
                     }
 
                     _windowGate.Wait(CreateWindowClose);
@@ -608,7 +599,7 @@ namespace System.Reactive.Linq.ObservableImpl
                     }
                 }
 
-                public void OnNext(TSource value)
+                public override void OnNext(TSource value)
                 {
                     lock (_gate)
                     {
@@ -616,23 +607,21 @@ namespace System.Reactive.Linq.ObservableImpl
                     }
                 }
 
-                public void OnError(Exception error)
+                public override void OnError(Exception error)
                 {
                     lock (_gate)
                     {
                         _window.OnError(error);
-                        base._observer.OnError(error);
-                        base.Dispose();
+                        ForwardOnError(error);
                     }
                 }
 
-                public void OnCompleted()
+                public override void OnCompleted()
                 {
                     lock (_gate)
                     {
                         _window.OnCompleted();
-                        base._observer.OnCompleted();
-                        base.Dispose();
+                        ForwardOnCompleted();
                     }
                 }
             }
@@ -653,7 +642,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
             protected override IDisposable Run(_ sink) => sink.Run(this);
 
-            internal sealed class _ : Sink<IObservable<TSource>>, IObserver<TSource>
+            internal sealed class _ : Sink<TSource, IObservable<TSource>> 
             {
                 private readonly object _gate = new object();
 
@@ -676,7 +665,7 @@ namespace System.Reactive.Linq.ObservableImpl
                     _refCountDisposable = new RefCountDisposable(d);
 
                     var window = new WindowObservable<TSource>(_window, _refCountDisposable);
-                    base._observer.OnNext(window);
+                    ForwardOnNext(window);
 
                     d.Add(parent._source.SubscribeSafe(this));
                     d.Add(parent._windowBoundaries.SubscribeSafe(new WindowClosingObserver(this)));
@@ -701,7 +690,7 @@ namespace System.Reactive.Linq.ObservableImpl
                             _parent._window = new Subject<TSource>();
 
                             var window = new WindowObservable<TSource>(_parent._window, _parent._refCountDisposable);
-                            _parent._observer.OnNext(window);
+                            _parent.ForwardOnNext(window);
                         }
                     }
 
@@ -716,7 +705,7 @@ namespace System.Reactive.Linq.ObservableImpl
                     }
                 }
 
-                public void OnNext(TSource value)
+                public override void OnNext(TSource value)
                 {
                     lock (_gate)
                     {
@@ -724,23 +713,21 @@ namespace System.Reactive.Linq.ObservableImpl
                     }
                 }
 
-                public void OnError(Exception error)
+                public override void OnError(Exception error)
                 {
                     lock (_gate)
                     {
                         _window.OnError(error);
-                        base._observer.OnError(error);
-                        base.Dispose();
+                        ForwardOnError(error);
                     }
                 }
 
-                public void OnCompleted()
+                public override void OnCompleted()
                 {
                     lock (_gate)
                     {
                         _window.OnCompleted();
-                        base._observer.OnCompleted();
-                        base.Dispose();
+                        ForwardOnCompleted();
                     }
                 }
             }

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

@@ -23,7 +23,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
         protected override IDisposable Run(_ sink) => sink.Run(_first, _second);
 
-        internal sealed class _ : Sink<TResult>
+        internal sealed class _ : IdentitySink<TResult>
         {
             private readonly Func<TFirst, TSecond, TResult> _resultSelector;
 
@@ -68,8 +68,7 @@ namespace System.Reactive.Linq.ObservableImpl
                 {
                     lock (_parent._gate)
                     {
-                        _parent._observer.OnCompleted();
-                        _parent.Dispose();
+                        _parent.ForwardOnCompleted();
                     }
                 }
 
@@ -77,8 +76,7 @@ namespace System.Reactive.Linq.ObservableImpl
                 {
                     lock (_parent._gate)
                     {
-                        _parent._observer.OnError(error);
-                        _parent.Dispose();
+                        _parent.ForwardOnError(error);
                     }
                 }
 
@@ -104,8 +102,7 @@ namespace System.Reactive.Linq.ObservableImpl
                         {
                             lock (_parent._gate)
                             {
-                                _parent._observer.OnError(ex);
-                                _parent.Dispose();
+                                _parent.ForwardOnError(ex);
                             }
 
                             return;
@@ -113,7 +110,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
                         lock (_parent._gate)
                         {
-                            _parent._observer.OnNext(res);
+                            _parent.ForwardOnNext(res);
                         }
                     }
                 }
@@ -139,8 +136,7 @@ namespace System.Reactive.Linq.ObservableImpl
                 {
                     lock (_parent._gate)
                     {
-                        _parent._observer.OnError(error);
-                        _parent.Dispose();
+                        _parent.ForwardOnError(error);
                     }
                 }
 

+ 31 - 63
Rx.NET/Source/src/System.Reactive/Linq/Observable/Zip.cs

@@ -30,7 +30,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
             protected override IDisposable Run(_ sink) => sink.Run(_first, _second);
 
-            internal sealed class _ : Sink<TResult>
+            internal sealed class _ : IdentitySink<TResult>
             {
                 private readonly Func<TFirst, TSecond, TResult> _resultSelector;
 
@@ -95,19 +95,17 @@ namespace System.Reactive.Linq.ObservableImpl
                                 }
                                 catch (Exception ex)
                                 {
-                                    _parent._observer.OnError(ex);
-                                    _parent.Dispose();
+                                    _parent.ForwardOnError(ex);
                                     return;
                                 }
 
-                                _parent._observer.OnNext(res);
+                                _parent.ForwardOnNext(res);
                             }
                             else
                             {
                                 if (_other.Done)
                                 {
-                                    _parent._observer.OnCompleted();
-                                    _parent.Dispose();
+                                    _parent.ForwardOnCompleted();
                                     return;
                                 }
 
@@ -120,8 +118,7 @@ namespace System.Reactive.Linq.ObservableImpl
                     {
                         lock (_parent._gate)
                         {
-                            _parent._observer.OnError(error);
-                            _parent.Dispose();
+                            _parent.ForwardOnError(error);
                         }
                     }
 
@@ -133,8 +130,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
                             if (_other.Done)
                             {
-                                _parent._observer.OnCompleted();
-                                _parent.Dispose();
+                                _parent.ForwardOnCompleted();
                                 return;
                             }
                             else
@@ -184,19 +180,17 @@ namespace System.Reactive.Linq.ObservableImpl
                                 }
                                 catch (Exception ex)
                                 {
-                                    _parent._observer.OnError(ex);
-                                    _parent.Dispose();
+                                    _parent.ForwardOnError(ex);
                                     return;
                                 }
 
-                                _parent._observer.OnNext(res);
+                                _parent.ForwardOnNext(res);
                             }
                             else
                             {
                                 if (_other.Done)
                                 {
-                                    _parent._observer.OnCompleted();
-                                    _parent.Dispose();
+                                    _parent.ForwardOnCompleted();
                                     return;
                                 }
 
@@ -209,8 +203,7 @@ namespace System.Reactive.Linq.ObservableImpl
                     {
                         lock (_parent._gate)
                         {
-                            _parent._observer.OnError(error);
-                            _parent.Dispose();
+                            _parent.ForwardOnError(error);
                         }
                     }
 
@@ -222,8 +215,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
                             if (_other.Done)
                             {
-                                _parent._observer.OnCompleted();
-                                _parent.Dispose();
+                                _parent.ForwardOnCompleted();
                                 return;
                             }
                             else
@@ -258,7 +250,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
             protected override IDisposable Run(_ sink) => sink.Run(_first, _second);
 
-            internal sealed class _ : Sink<TResult>, IObserver<TFirst>
+            internal sealed class _ : Sink<TFirst, TResult> 
             {
                 private readonly Func<TFirst, TSecond, TResult> _resultSelector;
 
@@ -285,8 +277,7 @@ namespace System.Reactive.Linq.ObservableImpl
                     }
                     catch (Exception exception)
                     {
-                        base._observer.OnError(exception);
-                        base.Dispose();
+                        ForwardOnError(exception);
                         return Disposable.Empty;
                     }
 
@@ -295,7 +286,7 @@ namespace System.Reactive.Linq.ObservableImpl
                     return StableCompositeDisposable.Create(leftSubscription, _rightEnumerator);
                 }
 
-                public void OnNext(TFirst value)
+                public override void OnNext(TFirst value)
                 {
                     var hasNext = false;
                     try
@@ -304,8 +295,7 @@ namespace System.Reactive.Linq.ObservableImpl
                     }
                     catch (Exception ex)
                     {
-                        base._observer.OnError(ex);
-                        base.Dispose();
+                        ForwardOnError(ex);
                         return;
                     }
 
@@ -318,8 +308,7 @@ namespace System.Reactive.Linq.ObservableImpl
                         }
                         catch (Exception ex)
                         {
-                            base._observer.OnError(ex);
-                            base.Dispose();
+                            ForwardOnError(ex);
                             return;
                         }
 
@@ -330,31 +319,17 @@ namespace System.Reactive.Linq.ObservableImpl
                         }
                         catch (Exception ex)
                         {
-                            base._observer.OnError(ex);
-                            base.Dispose();
+                            ForwardOnError(ex);
                             return;
                         }
 
-                        base._observer.OnNext(result);
+                        ForwardOnNext(result);
                     }
                     else
                     {
-                        base._observer.OnCompleted();
-                        base.Dispose();
+                        ForwardOnCompleted();
                     }
                 }
-
-                public void OnError(Exception error)
-                {
-                    base._observer.OnError(error);
-                    base.Dispose();
-                }
-
-                public void OnCompleted()
-                {
-                    base._observer.OnCompleted();
-                    base.Dispose();
-                }
             }
         }
     }
@@ -372,7 +347,7 @@ namespace System.Reactive.Linq.ObservableImpl
         void Done(int index);
     }
 
-    internal abstract class ZipSink<TResult> : Sink<TResult>, IZip
+    internal abstract class ZipSink<TResult> : IdentitySink<TResult>, IZip
     {
         protected readonly object _gate;
 
@@ -411,12 +386,11 @@ namespace System.Reactive.Linq.ObservableImpl
                 }
                 catch (Exception ex)
                 {
-                    base._observer.OnError(ex);
-                    base.Dispose();
+                    ForwardOnError(ex);
                     return;
                 }
 
-                base._observer.OnNext(res);
+                ForwardOnNext(res);
             }
             else
             {
@@ -432,8 +406,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
                 if (allOthersDone)
                 {
-                    base._observer.OnCompleted();
-                    base.Dispose();
+                    ForwardOnCompleted();
                 }
             }
         }
@@ -442,8 +415,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
         public void Fail(Exception error)
         {
-            base._observer.OnError(error);
-            base.Dispose();
+            ForwardOnError(error);
         }
 
         public void Done(int index)
@@ -462,8 +434,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
             if (allDone)
             {
-                base._observer.OnCompleted();
-                base.Dispose();
+                ForwardOnCompleted();
                 return;
             }
         }
@@ -537,7 +508,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
         protected override IDisposable Run(_ sink) => sink.Run();
 
-        internal sealed class _ : Sink<IList<TSource>>
+        internal sealed class _ : IdentitySink<IList<TSource>>
         {
             private readonly Zip<TSource> _parent;
 
@@ -598,23 +569,21 @@ namespace System.Reactive.Linq.ObservableImpl
                             res.Add(_queues[i].Dequeue());
                         }
 
-                        base._observer.OnNext(res);
+                        ForwardOnNext(res);
                     }
                     else if (_isDone.AllExcept(index))
                     {
-                        base._observer.OnCompleted();
-                        base.Dispose();
+                        ForwardOnCompleted();
                         return;
                     }
                 }
             }
 
-            private void OnError(Exception error)
+            private new void OnError(Exception error)
             {
                 lock (_gate)
                 {
-                    base._observer.OnError(error);
-                    base.Dispose();
+                    ForwardOnError(error);
                 }
             }
 
@@ -626,8 +595,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
                     if (_isDone.All())
                     {
-                        base._observer.OnCompleted();
-                        base.Dispose();
+                        ForwardOnCompleted();
                         return;
                     }
                     else

この差分においてかなりの量のファイルが変更されているため、一部のファイルを表示していません