Browse Source

4.x: Fix long sequence ObserveOn StackOverflowException upon Dispose

akarnokd 7 years ago
parent
commit
53096fbaab

+ 4 - 1
Rx.NET/Source/src/System.Reactive/Internal/ScheduledObserver.cs

@@ -536,7 +536,10 @@ namespace System.Reactive
 
             if (Interlocked.Decrement(ref _wip) != 0)
             {
-                return recursiveScheduler.Schedule(this, DRAIN_SHORT_RUNNING);
+                // Don't return the disposable of Schedule() because that may chain together
+                // a long string of ScheduledItems causing StackOverflowException upon Dispose()
+                var d = recursiveScheduler.Schedule(this, DRAIN_SHORT_RUNNING);
+                Disposable.TrySetMultiple(ref _task, d);
             }
             return Disposable.Empty;
         }

+ 13 - 0
Rx.NET/Source/tests/Tests.System.Reactive/Tests/Linq/Observable/ObserveOnTest.cs

@@ -645,6 +645,19 @@ namespace ReactiveTests.Tests
             );
         }
 
+        [Fact]
+        public void ObserveOn_EventLoop_Long()
+        {
+            var _scheduler1 = new EventLoopScheduler();
+            var N = 1_000_000;
+
+            var cde = new CountdownEvent(1);
+
+            Observable.Range(1, N).ObserveOn(_scheduler1)
+                .Subscribe(v => { }, () => cde.Signal());
+
+            Assert.True(cde.Wait(5000), "Timeout!");
+        }
     }
 
     internal class MyCtx : SynchronizationContext