From db4e9b9baead8cb273bbd6b358a870436a8b0f23 Mon Sep 17 00:00:00 2001 From: "gel@microsoft.com" Date: Wed, 3 May 2023 15:45:47 -0700 Subject: [PATCH] Move potential expensive task of ItemManager to ThreadPool thread --- .../AsyncCompletion/ItemManager.CompletionListUpdater.cs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/EditorFeatures/Core/IntelliSense/AsyncCompletion/ItemManager.CompletionListUpdater.cs b/src/EditorFeatures/Core/IntelliSense/AsyncCompletion/ItemManager.CompletionListUpdater.cs index 3219cdae38211..e64b992fa55fb 100644 --- a/src/EditorFeatures/Core/IntelliSense/AsyncCompletion/ItemManager.CompletionListUpdater.cs +++ b/src/EditorFeatures/Core/IntelliSense/AsyncCompletion/ItemManager.CompletionListUpdater.cs @@ -20,6 +20,7 @@ using Microsoft.VisualStudio.Language.Intellisense.AsyncCompletion; using Microsoft.VisualStudio.Language.Intellisense.AsyncCompletion.Data; using Microsoft.VisualStudio.Text; +using Microsoft.VisualStudio.Threading; using Roslyn.Utilities; using RoslynCompletionItem = Microsoft.CodeAnalysis.Completion.CompletionItem; using VSCompletionItem = Microsoft.VisualStudio.Language.Intellisense.AsyncCompletion.Data.CompletionItem; @@ -139,7 +140,7 @@ public CompletionListUpdater( // Determine the list of items to be included in the completion list. // This is computed based on the filter text as well as the current // selection of filters and expander. - AddCompletionItems(itemsToBeIncluded, threadLocalPatternMatchHelper, cancellationToken); + await AddCompletionItemsAsync(itemsToBeIncluded, threadLocalPatternMatchHelper, cancellationToken).ConfigureAwait(false); // Decide if we want to dismiss an empty completion list based on CompletionRules and filter usage. if (itemsToBeIncluded.Count == 0) @@ -236,7 +237,7 @@ private bool ShouldDismissCompletionListImmediately() return false; } - private void AddCompletionItems(List list, ThreadLocal threadLocalPatternMatchHelper, CancellationToken cancellationToken) + private async Task AddCompletionItemsAsync(List list, ThreadLocal threadLocalPatternMatchHelper, CancellationToken cancellationToken) { // Convert initial and update trigger reasons to corresponding Roslyn type so // we can interact with Roslyn's completion system @@ -249,6 +250,9 @@ private void AddCompletionItems(List list, ThreadLocal(); var includedDefaults = new ConcurrentDictionary(); + // Make sure we are on threadpool thread before running PLinq query to avoid sync waiting on the special high-pri thread of async-completion. + await TaskScheduler.Default; + Enumerable.Range(0, _snapshotData.InitialSortedItemList.Count) .AsParallel() .WithCancellation(cancellationToken) @@ -258,6 +262,7 @@ private void AddCompletionItems(List list, ThreadLocal