diff --git a/src/NzbDrone.Core/Messaging/Commands/CommandQueue.cs b/src/NzbDrone.Core/Messaging/Commands/CommandQueue.cs index c5b4c5772..ae92ca94e 100644 --- a/src/NzbDrone.Core/Messaging/Commands/CommandQueue.cs +++ b/src/NzbDrone.Core/Messaging/Commands/CommandQueue.cs @@ -23,6 +23,8 @@ namespace NzbDrone.Core.Messaging.Commands lock (_mutex) { _items.Add(item); + + Monitor.PulseAll(_mutex); } } @@ -68,6 +70,8 @@ namespace NzbDrone.Core.Messaging.Commands { _items.Remove(command); } + + Monitor.PulseAll(_mutex); } } @@ -83,6 +87,8 @@ namespace NzbDrone.Core.Messaging.Commands { _items.Remove(command); rval = true; + + Monitor.PulseAll(_mutex); } } @@ -102,14 +108,39 @@ namespace NzbDrone.Core.Messaging.Commands public IEnumerable GetConsumingEnumerable(CancellationToken cancellationToken) { + cancellationToken.Register(PulseAllConsumers); + while (!cancellationToken.IsCancellationRequested) { - if (TryGet(out var command)) + CommandModel command = null; + + lock (_mutex) + { + if (cancellationToken.IsCancellationRequested) + { + break; + } + + if (!TryGet(out command)) + { + Monitor.Wait(_mutex); + continue; + } + } + + if (command != null) { yield return command; } + } + } - Thread.Sleep(10); + public void PulseAllConsumers() + { + // Signal all consumers to reevaluate cancellation token + lock (_mutex) + { + Monitor.PulseAll(_mutex); } } diff --git a/src/NzbDrone.Core/Messaging/Commands/CommandQueueManager.cs b/src/NzbDrone.Core/Messaging/Commands/CommandQueueManager.cs index ca662c3e4..d06b5051c 100644 --- a/src/NzbDrone.Core/Messaging/Commands/CommandQueueManager.cs +++ b/src/NzbDrone.Core/Messaging/Commands/CommandQueueManager.cs @@ -188,6 +188,8 @@ namespace NzbDrone.Core.Messaging.Commands public void Complete(CommandModel command, string message) { Update(command, CommandStatus.Completed, message); + + _commandQueue.PulseAllConsumers(); } public void Fail(CommandModel command, string message, Exception e) @@ -195,6 +197,8 @@ namespace NzbDrone.Core.Messaging.Commands command.Exception = e.ToString(); Update(command, CommandStatus.Failed, message); + + _commandQueue.PulseAllConsumers(); } public void Requeue()