/
githubmirror
/
roslyn
Обзор
Документация
Войти
/
githubmirror
/
roslyn
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
src/VisualStudio/Core/Def/LanguageService/AbstractCreateServicesOnTextViewConnection.cs
119 строк
5 KB
Jason Malinowski
Remove use of DisposalToken if we can just call Dispose() instead
04 авг 2026, 23:51
04 авг 2026, 23:51
5ab65fc
Код
Авторство
О чём код?
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Threading; using System.Threading.Tasks; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.Collections; using Microsoft.CodeAnalysis.Completion; using Microsoft.CodeAnalysis.Host; using Microsoft.CodeAnalysis.Options; using Microsoft.CodeAnalysis.Shared.Extensions; using Microsoft.CodeAnalysis.Shared.TestHooks; using Microsoft.CodeAnalysis.Snippets; using Microsoft.CodeAnalysis.Threading; using Microsoft.VisualStudio.Text; using Microsoft.VisualStudio.Text.Editor; namespace Microsoft.VisualStudio.LanguageServices.Implementation.LanguageService; /// <summary> /// Creates services on the first connection of an applicable subject buffer to an IWpfTextView. /// This ensures the services are available by the time an open document or the interactive window needs them. /// </summary> internal abstract class AbstractCreateServicesOnTextViewConnection : IWpfTextViewConnectionListener, IDisposable { private readonly string _languageName; private readonly AsyncBatchingWorkQueue<ProjectId?> _workQueue; private readonly WorkspaceEventRegistration _workspaceDocumentOpenedDisposer; private bool _initialized = false; protected VisualStudioWorkspace Workspace { get; } protected IGlobalOptionService GlobalOptions { get; } protected virtual Task InitializeServiceForProjectWithOpenedDocumentAsync(Project project) => Task.CompletedTask; public AbstractCreateServicesOnTextViewConnection( VisualStudioWorkspace workspace, IGlobalOptionService globalOptions, IAsynchronousOperationListenerProvider listenerProvider, string languageName) { Workspace = workspace; GlobalOptions = globalOptions; _languageName = languageName; _workQueue = new AsyncBatchingWorkQueue<ProjectId?>( TimeSpan.FromSeconds(1), BatchProcessProjectsWithOpenedDocumentAsync, EqualityComparer<ProjectId?>.Default, listenerProvider.GetListener(FeatureAttribute.CompletionSet)); _workspaceDocumentOpenedDisposer = Workspace.RegisterDocumentOpenedHandler(QueueWorkOnDocumentOpened); } public void Dispose() { _workspaceDocumentOpenedDisposer.Dispose(); _workQueue.Dispose(); } void IWpfTextViewConnectionListener.SubjectBuffersConnected(IWpfTextView textView, ConnectionReason reason, Collection<ITextBuffer> subjectBuffers) { if (!_initialized) { _initialized = true; // use `null` to trigger per VS session intialization task _workQueue.AddWork((ProjectId?)null); } } void IWpfTextViewConnectionListener.SubjectBuffersDisconnected(IWpfTextView textView, ConnectionReason reason, Collection<ITextBuffer> subjectBuffers) { } private async ValueTask BatchProcessProjectsWithOpenedDocumentAsync(ImmutableSegmentedList<ProjectId?> projectIds, CancellationToken cancellationToken) { foreach (var projectId in projectIds) { cancellationToken.ThrowIfCancellationRequested(); if (projectId is null) { InitializePerVSSessionServices(); } else if (Workspace.CurrentSolution.GetProject(projectId) is Project project) { // Preload project completion providers at document open also helps avoid redundant file reads // from a race caused by multiple features (codefix, refactoring, etc.) attempting to get extensions // from analyzer references at the same time when they are not cached. if (project.GetLanguageService<CompletionService>() is CompletionService completionService) completionService.TriggerLoadProjectProviders(project, GlobalOptions.GetCompletionOptions(project.Language)); await InitializeServiceForProjectWithOpenedDocumentAsync(project).ConfigureAwait(false); } } } private void QueueWorkOnDocumentOpened(DocumentEventArgs e) { if (e.Document.Project.Language == _languageName) _workQueue.AddWork(e.Document.Project.Id); } private void InitializePerVSSessionServices() { var languageServices = Workspace.Services.GetExtendedLanguageServices(_languageName); _ = languageServices.GetService<ISnippetInfoService>(); // Preload completion providers on a background thread since assembly loads can be slow // https://devdiv.visualstudio.com/DevDiv/_workitems/edit/1242321 languageServices.GetService<CompletionService>()?.LoadImportedProviders(); } }