public void Analyze(Deque <AnalysisUnit> queue, CancellationToken cancel, Action <int> reportQueueSize = null, int reportQueueInterval = 1) { if (cancel.IsCancellationRequested) { return; } try { // Including a marker at the end of the queue allows us to see in // the log how frequently the queue empties. var endOfQueueMarker = new AnalysisUnit(null, null); int queueCountAtStart = queue.Count; int reportInterval = reportQueueInterval - 1; if (queueCountAtStart > 0) { queue.Append(endOfQueueMarker); } while (queue.Count > 0 && !cancel.IsCancellationRequested) { _unit = queue.PopLeft(); if (_unit == endOfQueueMarker) { AnalysisLog.EndOfQueue(queueCountAtStart, queue.Count); if (reportInterval < 0 && reportQueueSize != null) { reportQueueSize(queue.Count); } queueCountAtStart = queue.Count; if (queueCountAtStart > 0) { queue.Append(endOfQueueMarker); } continue; } AnalysisLog.Dequeue(queue, _unit); if (reportInterval == 0 && reportQueueSize != null) { reportQueueSize(queue.Count); reportInterval = reportQueueInterval - 1; } else if (reportInterval > 0) { reportInterval -= 1; } _unit.IsInQueue = false; SetCurrentUnit(_unit); AnalyzedEntries.Add(_unit.ProjectEntry); _unit.Analyze(this, cancel); } if (reportQueueSize != null) { reportQueueSize(0); } if (cancel.IsCancellationRequested) { AnalysisLog.Cancelled(queue); } } finally { AnalysisLog.Flush(); AnalyzedEntries.Remove(null); } }