private void Connect() { _workQueue.AssertIsForeground(); _eventSource.Changed += OnChanged; _eventSource.UIUpdatesResumed += OnUIUpdatesResumed; _eventSource.UIUpdatesPaused += OnUIUpdatesPaused; if (_dataSource.TextChangeBehavior.HasFlag(TaggerTextChangeBehavior.TrackTextChanges)) { _subjectBuffer.Changed += OnSubjectBufferChanged; } if (_dataSource.CaretChangeBehavior.HasFlag(TaggerCaretChangeBehavior.RemoveAllTagsOnCaretMoveOutsideOfTag)) { if (_textViewOpt == null) { throw new ArgumentException( nameof(_dataSource.CaretChangeBehavior) + " can only be specified for an " + nameof(IViewTaggerProvider)); } _textViewOpt.Caret.PositionChanged += OnCaretPositionChanged; } // Tell the interaction object to start issuing events. _eventSource.Connect(); }
private async Task EnqueueProcessSnapshotWorkerAsync(Document document, CancellationToken cancellationToken) { // we will enqueue new one soon, cancel pending refresh right away _reportChangeCancellationSource.Cancel(); var newText = await document.GetTextAsync(cancellationToken).ConfigureAwait(false); var snapshot = newText.FindCorrespondingEditorTextSnapshot(); if (snapshot == null) { // It's possible that we're seeing a notification for an update that happened // just before the file was opened, and so the document we're given is still the // old one. return; } // TODO - Cleanup once experiment completed - https://github.com/dotnet/roslyn/projects/45#card-27261853 var latencyTracker = ShouldLogLocalTelemetry(document.Project.Language) ? new RequestLatencyTracker(SyntacticLspLogger.RequestType.SyntacticTagger) : null; using (latencyTracker) { // preemptively parse file in background so that when we are called from tagger from UI thread, we have tree ready. // F#/typescript and other languages that doesn't support syntax tree will return null here. _ = await document.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false); } lock (_gate) { _lastProcessedSnapshot = snapshot; _lastProcessedDocument = document; } _reportChangeCancellationSource = new CancellationTokenSource(); _notificationService.RegisterNotification(() => { _workQueue.AssertIsForeground(); ReportChangedSpan(snapshot.GetFullSpan()); }, ReportChangeDelayInMilliseconds, _listener.BeginAsyncOperation("ReportEntireFileChanged"), _reportChangeCancellationSource.Token); }
private async Task EnqueueParseSnapshotWorkerAsync(Document document, ITextSnapshot snapshot, CancellationToken cancellationToken) { // preemptively parse file in background so that when we are called from tagger from UI thread, we have tree ready. var syntaxTree = await document.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false); lock (_gate) { _lastParsedSnapshot = snapshot; _lastParsedDocument = document; } _reportChangeCancellationSource = new CancellationTokenSource(); _notificationService.RegisterNotification(() => { _workQueue.AssertIsForeground(); ReportChangedSpan(snapshot.GetFullSpan()); }, ReportChangeDelayInMilliseconds, _listener.BeginAsyncOperation("ReportEntireFileChanged"), _reportChangeCancellationSource.Token); }
private async Task EnqueueProcessSnapshotWorkerAsync(Document document, CancellationToken cancellationToken) { // we will enqueue new one soon, cancel pending refresh right away _reportChangeCancellationSource.Cancel(); var newText = await document.GetTextAsync(cancellationToken).ConfigureAwait(false); var snapshot = newText.FindCorrespondingEditorTextSnapshot(); if (snapshot == null) { // It's possible that we're seeing a notification for an update that happened // just before the file was opened, and so the document we're given is still the // old one. return; } // preemptively parse file in background so that when we are called from tagger from UI thread, we have tree ready. // F#/typescript and other languages that doesn't support syntax tree will return null here. _ = await document.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false); lock (_gate) { _lastProcessedSnapshot = snapshot; _lastProcessedDocument = document; } _reportChangeCancellationSource = new CancellationTokenSource(); _notificationService.RegisterNotification(() => { _workQueue.AssertIsForeground(); ReportChangedSpan(snapshot.GetFullSpan()); }, ReportChangeDelayInMilliseconds, _listener.BeginAsyncOperation("ReportEntireFileChanged"), _reportChangeCancellationSource.Token); }
/// <summary> /// Wait until all tasks have been completed. NOTE that this will do a pumping wait if /// called on the UI thread. Also, it isn't guaranteed to be stable in the case of tasks /// enqueuing other tasks in arbitrary orders, though it does support our common pattern of /// "timer task->background task->foreground task with results" /// /// Use this method very judiciously. Most of the time, we should be able to just use /// IAsynchronousOperationListener for tests. /// </summary> public void WaitUntilCompletion() { _asynchronousSerialWorkQueue.AssertIsForeground(); _asynchronousSerialWorkQueue.WaitForPendingBackgroundWork(); }