From eb4e95e5db46de3bcf1cdb142ec1e9fae31f11da Mon Sep 17 00:00:00 2001 From: Matt Nadareski Date: Wed, 31 Mar 2021 21:26:55 -0700 Subject: [PATCH] Fix ProcessingQueue disposal (fixes #267) --- MPF.Library/Data/ProcessingQueue.cs | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/MPF.Library/Data/ProcessingQueue.cs b/MPF.Library/Data/ProcessingQueue.cs index 00ccd0e5..4a31c8bd 100644 --- a/MPF.Library/Data/ProcessingQueue.cs +++ b/MPF.Library/Data/ProcessingQueue.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Concurrent; +using System.Threading; using System.Threading.Tasks; namespace MPF.Data @@ -21,11 +22,17 @@ namespace MPF.Data /// private readonly Task ProcessingTask; + /// + /// Cancellation method for the processing task + /// + private readonly CancellationTokenSource TokenSource; + public ProcessingQueue(Action customProcessing) { this.InternalQueue = new ConcurrentQueue(); this.CustomProcessing = customProcessing; - this.ProcessingTask = Task.Run(() => ProcessQueue()); + this.TokenSource = new CancellationTokenSource(); + this.ProcessingTask = Task.Run(() => ProcessQueue(), this.TokenSource.Token); } /// @@ -33,6 +40,8 @@ namespace MPF.Data /// public void Dispose() { + this.TokenSource.Cancel(); + while (!this.ProcessingTask.IsCompleted) ; this.ProcessingTask.Dispose(); } @@ -52,12 +61,16 @@ namespace MPF.Data { while (true) { + // If cancellation was requested, just do it + if (this.TokenSource.IsCancellationRequested) + break; + // Nothing in the queue means we get to idle - if (InternalQueue.Count == 0) + if (this.InternalQueue.Count == 0) continue; // Get the next item from the queue - if (!InternalQueue.TryDequeue(out T nextItem)) + if (!this.InternalQueue.TryDequeue(out T nextItem)) continue; // Invoke the lambda, if possible