提交 43920675 编写于 作者: S Sam Harwell

Handle empty queue in WaitForPendingWorkAsync

Cancellation allows item removal from the pending work queue from non-UI threads,
so the UI thread handling needs to account for the possibility of it being empty
after WaitForItemsAsync completes.
上级 b419ef49
...@@ -196,26 +196,29 @@ private void NotifyOnForegroundWorker() ...@@ -196,26 +196,29 @@ private void NotifyOnForegroundWorker()
private async Task WaitForPendingWorkAsync() private async Task WaitForPendingWorkAsync()
{ {
await _workQueue.WaitForItemsAsync().ConfigureAwait(false);
while (true) while (true)
{ {
var current = Environment.TickCount; await _workQueue.WaitForItemsAsync().ConfigureAwait(false);
var nextItem = _workQueue.PeekNextItemTime(); if (!_workQueue.TryPeekNextItemTime(out var nextItem))
{
// Need to go back and wait for an item
continue;
}
// The next item is ready to run // The next item is ready to run
if (nextItem - current <= 0) if (nextItem - Environment.TickCount <= 0)
{ {
break; break;
} }
// wait some and re-check since there could be another one inserted before the first one while we were waiting. // wait some and re-check since there could be another one inserted before the first one while we were waiting.
await Task.Delay(MinimumDelayBetweenProcessing).ConfigureAwait(continueOnCapturedContext: false); await Task.Delay(MinimumDelayBetweenProcessing).ConfigureAwait(false);
} }
// Throttle how often we run by waiting MinimumDelayBetweenProcessing since the last time we processed notifications // Throttle how often we run by waiting MinimumDelayBetweenProcessing since the last time we processed notifications
if (Environment.TickCount - _lastProcessedTimeInMS < MinimumDelayBetweenProcessing) if (Environment.TickCount - _lastProcessedTimeInMS < MinimumDelayBetweenProcessing)
{ {
await Task.Delay(MinimumDelayBetweenProcessing).ConfigureAwait(continueOnCapturedContext: false); await Task.Delay(MinimumDelayBetweenProcessing).ConfigureAwait(false);
} }
} }
...@@ -344,12 +347,18 @@ private void Enqueue_NoLock(LinkedListNode<PendingWork> entry) ...@@ -344,12 +347,18 @@ private void Enqueue_NoLock(LinkedListNode<PendingWork> entry)
return; return;
} }
public int PeekNextItemTime() public bool TryPeekNextItemTime(out int minimumRunPoint)
{ {
lock (_gate) lock (_gate)
{ {
Contract.Requires(_list.Count > 0); if (_list.Count == 0)
return _list.First.Value.MinimumRunPointInMS; {
minimumRunPoint = 0;
return false;
}
minimumRunPoint = _list.First.Value.MinimumRunPointInMS;
return true;
} }
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册