diff --git a/src/NzbDrone.Core/Messaging/Commands/CommandQueue.cs b/src/NzbDrone.Core/Messaging/Commands/CommandQueue.cs index c5b4c5772..b6b686c0c 100644 --- a/src/NzbDrone.Core/Messaging/Commands/CommandQueue.cs +++ b/src/NzbDrone.Core/Messaging/Commands/CommandQueue.cs @@ -23,6 +23,8 @@ public void Add(CommandModel item) lock (_mutex) { _items.Add(item); + + Monitor.PulseAll(_mutex); } } @@ -68,6 +70,8 @@ public void RemoveMany(IEnumerable commands) { _items.Remove(command); } + + Monitor.PulseAll(_mutex); } } @@ -83,6 +87,8 @@ public bool RemoveIfQueued(int id) { _items.Remove(command); rval = true; + + Monitor.PulseAll(_mutex); } } @@ -102,18 +108,43 @@ public IEnumerable GetConsumingEnumerable() 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 bool TryGet(out CommandModel item) + public void PulseAllConsumers() + { + // Signal all consumers to reevaluate cancellation token + lock (_mutex) + { + Monitor.PulseAll(_mutex); + } + } + + private bool TryGet(out CommandModel item) { var rval = true; item = default(CommandModel); diff --git a/src/NzbDrone.Core/Messaging/Commands/CommandQueueManager.cs b/src/NzbDrone.Core/Messaging/Commands/CommandQueueManager.cs index 715eabe6a..cf11f4320 100644 --- a/src/NzbDrone.Core/Messaging/Commands/CommandQueueManager.cs +++ b/src/NzbDrone.Core/Messaging/Commands/CommandQueueManager.cs @@ -190,6 +190,8 @@ public void Start(CommandModel command) public void Complete(CommandModel command, string message) { Update(command, CommandStatus.Completed, message); + + _commandQueue.PulseAllConsumers(); } public void Fail(CommandModel command, string message, Exception e) @@ -197,6 +199,8 @@ public void Fail(CommandModel command, string message, Exception e) command.Exception = e.ToString(); Update(command, CommandStatus.Failed, message); + + _commandQueue.PulseAllConsumers(); } public void Requeue()