private async Task ProcessDocumentAsync(Solution solution, ImmutableArray <IIncrementalAnalyzer> analyzers, WorkItem workItem, CancellationTokenSource source) { if (this.CancellationToken.IsCancellationRequested) { return; } var processedEverything = false; var documentId = workItem.DocumentId; try { using (Logger.LogBlock(FunctionId.WorkCoordinator_ProcessDocumentAsync, source.Token)) { var cancellationToken = source.Token; var document = solution.GetDocument(documentId); if (document != null) { await ProcessDocumentAnalyzersAsync(document, analyzers, workItem, cancellationToken).ConfigureAwait(false); } if (!cancellationToken.IsCancellationRequested) { processedEverything = true; } } } catch (Exception e) when(FatalError.ReportUnlessCanceled(e)) { throw ExceptionUtilities.Unreachable; } finally { // we got cancelled in the middle of processing the document. // let's make sure newly enqueued work item has all the flag needed. if (!processedEverything) { _workItemQueue.AddOrReplace(workItem.Retry(this.Listener.BeginAsyncOperation("ReenqueueWorkItem"))); } SolutionCrawlerLogger.LogProcessActiveFileDocument(_processor._logAggregator, documentId.Id, processedEverything); // remove one that is finished running _workItemQueue.RemoveCancellationSource(workItem.DocumentId); } }
private async Task ProcessDocumentAsync(ImmutableArray <IIncrementalAnalyzer> analyzers, WorkItem workItem, CancellationTokenSource source) { if (this.CancellationToken.IsCancellationRequested) { return; } var processedEverything = false; var documentId = workItem.DocumentId; try { using (Logger.LogBlock(FunctionId.WorkCoordinator_ProcessDocumentAsync, source.Token)) { var cancellationToken = source.Token; var document = _processingSolution.GetDocument(documentId); if (document != null) { // if we are called because a document is opened, we invalidate the document so that // it can be re-analyzed. otherwise, since newly opened document has same version as before // analyzer will simply return same data back if (workItem.MustRefresh && !workItem.IsRetry) { var isOpen = document.IsOpen(); await ProcessOpenDocumentIfNeeded(analyzers, workItem, document, isOpen, cancellationToken).ConfigureAwait(false); await ProcessCloseDocumentIfNeeded(analyzers, workItem, document, isOpen, cancellationToken).ConfigureAwait(false); } // check whether we are having special reanalyze request await ProcessReanalyzeDocumentAsync(workItem, document, cancellationToken).ConfigureAwait(false); await ProcessDocumentAnalyzersAsync(document, analyzers, workItem, cancellationToken).ConfigureAwait(false); } else { SolutionCrawlerLogger.LogProcessDocumentNotExist(this.Processor._logAggregator); RemoveDocument(documentId); } if (!cancellationToken.IsCancellationRequested) { processedEverything = true; } } } catch (Exception e) when(FatalError.ReportUnlessCanceled(e)) { throw ExceptionUtilities.Unreachable; } finally { // we got cancelled in the middle of processing the document. // let's make sure newly enqueued work item has all the flag needed. if (!processedEverything) { _workItemQueue.AddOrReplace(workItem.Retry(this.Listener.BeginAsyncOperation("ReenqueueWorkItem"))); } SolutionCrawlerLogger.LogProcessDocument(this.Processor._logAggregator, documentId.Id, processedEverything); // remove one that is finished running _workItemQueue.RemoveCancellationSource(workItem.DocumentId); } }