From fa3cdc6af2f74a55001cd48bd3786d69bc186c92 Mon Sep 17 00:00:00 2001 From: Eugene Baranov <220614+eugbaranov@users.noreply.github.com> Date: Fri, 19 Jul 2019 00:49:15 +0100 Subject: [PATCH] Disposing EventLoopScheduler with in-flight items (closes #286) --- .../Concurrency/EventLoopScheduler.cs | 12 ++++++++++-- .../Tests/Concurrency/EventLoopSchedulerTest.cs | 14 ++++++++++++++ 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/Rx.NET/Source/src/System.Reactive/Concurrency/EventLoopScheduler.cs b/Rx.NET/Source/src/System.Reactive/Concurrency/EventLoopScheduler.cs index ed68a66d14..0c0e62e217 100644 --- a/Rx.NET/Source/src/System.Reactive/Concurrency/EventLoopScheduler.cs +++ b/Rx.NET/Source/src/System.Reactive/Concurrency/EventLoopScheduler.cs @@ -153,7 +153,7 @@ public override IDisposable Schedule(TState state, TimeSpan dueTime, Fun { if (_disposed) { - throw new ObjectDisposedException(""); + throw new ObjectDisposedException(nameof(EventLoopScheduler)); } if (dueTime <= TimeSpan.Zero) @@ -351,7 +351,15 @@ private void Run() { if (!item.IsCanceled) { - item.Invoke(); + try + { + item.Invoke(); + } + catch (ObjectDisposedException ex) when (nameof(EventLoopScheduler).Equals(ex.ObjectName)) + { + // Since we are not inside the lock at this point + // the scheduler can be disposed before the item had a chance to run + } } } } diff --git a/Rx.NET/Source/tests/Tests.System.Reactive/Tests/Concurrency/EventLoopSchedulerTest.cs b/Rx.NET/Source/tests/Tests.System.Reactive/Tests/Concurrency/EventLoopSchedulerTest.cs index 24288732ea..44a0a26159 100644 --- a/Rx.NET/Source/tests/Tests.System.Reactive/Tests/Concurrency/EventLoopSchedulerTest.cs +++ b/Rx.NET/Source/tests/Tests.System.Reactive/Tests/Concurrency/EventLoopSchedulerTest.cs @@ -7,6 +7,7 @@ using System.Diagnostics; using System.Reactive.Concurrency; using System.Reactive.Disposables; +using System.Reactive.Linq; using System.Threading; using Microsoft.Reactive.Testing; using Xunit; @@ -41,6 +42,19 @@ public void EventLoop_Now() Assert.True(res.Seconds < 1); } + [Fact] + public void EventLoop_DisposeWithInFlightActions() + { + using (var scheduler = new EventLoopScheduler()) + using (var subscription = Observable + .Range(1, 10) + .ObserveOn(scheduler) + .Subscribe(_ => Thread.Sleep(50))) + { + Thread.Sleep(50); + } + } + [Fact] public void EventLoop_ScheduleAction() {