From 21b4eecf446cf35d7ae09ead3d8f5a9b10d1da89 Mon Sep 17 00:00:00 2001 From: DJGosnell Date: Mon, 7 Nov 2022 18:17:50 -0500 Subject: [PATCH] Rearragned thread dispatcher stopping internals to prevent disposal of collections prior to thread completion. --- .../Dispatcher/ThreadDispatcherTests.cs | 17 +++++++++++++++-- src/DtronixCommon/DtronixCommon.csproj | 2 +- .../Threading/Dispatcher/ThreadDispatcher.cs | 14 +++++++------- 3 files changed, 23 insertions(+), 10 deletions(-) diff --git a/src/DtronixCommon.Tests/Threading/Dispatcher/ThreadDispatcherTests.cs b/src/DtronixCommon.Tests/Threading/Dispatcher/ThreadDispatcherTests.cs index 2327a5d..d48bf81 100644 --- a/src/DtronixCommon.Tests/Threading/Dispatcher/ThreadDispatcherTests.cs +++ b/src/DtronixCommon.Tests/Threading/Dispatcher/ThreadDispatcherTests.cs @@ -169,13 +169,26 @@ void Wrapper(Action obj) var dispatcher = new ThreadDispatcher(1) { DispatcherExecutionWrapper = Wrapper }; dispatcher.Start(); - await Task.Delay(500); - // Dummy action. await dispatcher.Queue(() => { }); Assert.AreEqual(1, wrapperCallCount); } + [Test] + public async Task DispatcherStopsWhenRunningLongRunningTasks() + { + var dispatcher = new ThreadDispatcher(1); + dispatcher.Start(); + + // Dummy action. + for (int i = 0; i < 10; i++) + { + dispatcher.QueueFireForget(_ => { Thread.Sleep(250); }); + } + + Assert.IsTrue(dispatcher.Stop(400)); + } + } diff --git a/src/DtronixCommon/DtronixCommon.csproj b/src/DtronixCommon/DtronixCommon.csproj index 24072b6..74b0a71 100644 --- a/src/DtronixCommon/DtronixCommon.csproj +++ b/src/DtronixCommon/DtronixCommon.csproj @@ -2,7 +2,7 @@ net5.0;net6.0 enable - 0.6.5.0 + 0.6.6.0 enable 10 Dtronix diff --git a/src/DtronixCommon/Threading/Dispatcher/ThreadDispatcher.cs b/src/DtronixCommon/Threading/Dispatcher/ThreadDispatcher.cs index f29fdc0..6ab6394 100644 --- a/src/DtronixCommon/Threading/Dispatcher/ThreadDispatcher.cs +++ b/src/DtronixCommon/Threading/Dispatcher/ThreadDispatcher.cs @@ -171,16 +171,11 @@ public bool Stop(int timeout = 1000) for (int i = 0; i < _configs.ThreadCount; i++) _queues[0].TryAdd(new StopLoop()); - _cancellationTokenSource?.Cancel(); + // Stop adding any items. foreach (var queue in _queues) - { queue.CompleteAdding(); - queue.Dispose(); - } - - _queues = null; var stopSuccessful = true; // Join all the threads back to ensure they are complete. @@ -190,7 +185,12 @@ public bool Stop(int timeout = 1000) if (!thread.Join(timeout)) stopSuccessful = false; } - + + // Dispose of all the queues since the threads have now been stopped. + foreach (var queue in _queues) + queue.Dispose(); + + _queues = null; Threads = null; return stopSuccessful;