diff --git a/AzureBatchQueue/TimerBatch.cs b/AzureBatchQueue/TimerBatch.cs index 76d2a54..00998da 100644 --- a/AzureBatchQueue/TimerBatch.cs +++ b/AzureBatchQueue/TimerBatch.cs @@ -12,7 +12,7 @@ internal class TimerBatch readonly ILogger logger; readonly ConcurrentDictionary> items; - readonly Timer timer; + Timer? timer; BatchCompletedResult? completedResult; public TimerBatch(BatchQueue batchQueue, QueueMessage msg, int maxDequeueCount, ILogger logger) @@ -36,7 +36,7 @@ async Task Flush() { try { - await timer.DisposeAsync(); + DisposeTimer(); await DoFlush(); } @@ -57,6 +57,9 @@ async Task Flush() async Task DoFlush() { + if (completedResult != null) + return; + if (items.IsEmpty) { completedResult = BatchCompletedResult.FullyProcessed; @@ -77,6 +80,16 @@ async Task DoFlush() } } + /// + /// Set timer reference to null, so that call to timer in Complete() will not throw ObjectDisposedException + /// + void DisposeTimer() + { + var timerCopy = timer; + timer = null; + timerCopy.Dispose(); + } + QueueMessage Message() { var notCompletedItems = items.Values.Select(x => x.Item).ToArray(); @@ -93,13 +106,11 @@ public BatchItemCompleteResult Complete(string itemId) if (!res) throw new ItemNotFoundException(itemId); - if (items.IsEmpty) - { - timer.Change(TimeSpan.Zero, Timeout.InfiniteTimeSpan); - return BatchItemCompleteResult.BatchFullyProcessed; - } + if (!items.IsEmpty) + return BatchItemCompleteResult.Completed; - return BatchItemCompleteResult.Completed; + timer?.Change(TimeSpan.Zero, Timeout.InfiniteTimeSpan); + return BatchItemCompleteResult.BatchFullyProcessed; } public IEnumerable> Unpack()