Skip to content

Commit fc4c9a1

Browse files
remove synchronous blocking waits in async codepaths (#76465)
2 parents 31e5802 + 52e7d3b commit fc4c9a1

File tree

3 files changed

+66
-74
lines changed

3 files changed

+66
-74
lines changed

src/EditorFeatures/Core.Wpf/Suggestions/FixAll/FixMultipleOccurrencesService.cs

Lines changed: 59 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -8,85 +8,77 @@
88
using System.Collections.Immutable;
99
using System.Composition;
1010
using System.Threading;
11-
using Microsoft.CodeAnalysis.CodeActions;
11+
using System.Threading.Tasks;
1212
using Microsoft.CodeAnalysis.CodeFixes;
1313
using Microsoft.CodeAnalysis.Extensions;
1414
using Microsoft.CodeAnalysis.Host.Mef;
15-
using Microsoft.CodeAnalysis.Shared.TestHooks;
16-
using Roslyn.Utilities;
1715

18-
namespace Microsoft.CodeAnalysis.Editor.Implementation.Suggestions
16+
namespace Microsoft.CodeAnalysis.Editor.Implementation.Suggestions;
17+
18+
/// <summary>
19+
/// Service to compute and apply <see cref="FixMultipleCodeAction"/> code fixes.
20+
/// </summary>
21+
[ExportWorkspaceService(typeof(IFixMultipleOccurrencesService), ServiceLayer.Host), Shared]
22+
[method: ImportingConstructor]
23+
[method: Obsolete(MefConstruction.ImportingConstructorMessage, error: true)]
24+
internal sealed class FixMultipleOccurrencesService() : IFixMultipleOccurrencesService
1925
{
20-
/// <summary>
21-
/// Service to compute and apply <see cref="FixMultipleCodeAction"/> code fixes.
22-
/// </summary>
23-
[ExportWorkspaceService(typeof(IFixMultipleOccurrencesService), ServiceLayer.Host), Shared]
24-
internal sealed class FixMultipleOccurrencesService : IFixMultipleOccurrencesService
26+
public Task<Solution> GetFixAsync(
27+
ImmutableDictionary<Document, ImmutableArray<Diagnostic>> diagnosticsToFix,
28+
Workspace workspace,
29+
CodeFixProvider fixProvider,
30+
FixAllProvider fixAllProvider,
31+
string equivalenceKey,
32+
string waitDialogTitle,
33+
string waitDialogMessage,
34+
IProgress<CodeAnalysisProgress> progress,
35+
CancellationToken cancellationToken)
2536
{
26-
[ImportingConstructor]
27-
[Obsolete(MefConstruction.ImportingConstructorMessage, error: true)]
28-
public FixMultipleOccurrencesService(IAsynchronousOperationListenerProvider listenerProvider)
29-
{
30-
listenerProvider.GetListener(FeatureAttribute.LightBulb);
31-
}
37+
var fixMultipleState = FixAllState.Create(
38+
fixAllProvider, diagnosticsToFix, fixProvider, equivalenceKey);
3239

33-
public Solution GetFix(
34-
ImmutableDictionary<Document, ImmutableArray<Diagnostic>> diagnosticsToFix,
35-
Workspace workspace,
36-
CodeFixProvider fixProvider,
37-
FixAllProvider fixAllProvider,
38-
string equivalenceKey,
39-
string waitDialogTitle,
40-
string waitDialogMessage,
41-
IProgress<CodeAnalysisProgress> progress,
42-
CancellationToken cancellationToken)
43-
{
44-
var fixMultipleState = FixAllState.Create(
45-
fixAllProvider, diagnosticsToFix, fixProvider, equivalenceKey);
40+
return GetFixedSolutionAsync(
41+
fixMultipleState, workspace, waitDialogTitle, waitDialogMessage, progress, cancellationToken);
42+
}
4643

47-
return GetFixedSolution(
48-
fixMultipleState, workspace, waitDialogTitle, waitDialogMessage, progress, cancellationToken);
49-
}
44+
public Task<Solution> GetFixAsync(
45+
ImmutableDictionary<Project, ImmutableArray<Diagnostic>> diagnosticsToFix,
46+
Workspace workspace,
47+
CodeFixProvider fixProvider,
48+
FixAllProvider fixAllProvider,
49+
string equivalenceKey,
50+
string waitDialogTitle,
51+
string waitDialogMessage,
52+
IProgress<CodeAnalysisProgress> progress,
53+
CancellationToken cancellationToken)
54+
{
55+
var fixMultipleState = FixAllState.Create(
56+
fixAllProvider, diagnosticsToFix, fixProvider, equivalenceKey);
5057

51-
public Solution GetFix(
52-
ImmutableDictionary<Project, ImmutableArray<Diagnostic>> diagnosticsToFix,
53-
Workspace workspace,
54-
CodeFixProvider fixProvider,
55-
FixAllProvider fixAllProvider,
56-
string equivalenceKey,
57-
string waitDialogTitle,
58-
string waitDialogMessage,
59-
IProgress<CodeAnalysisProgress> progress,
60-
CancellationToken cancellationToken)
61-
{
62-
var fixMultipleState = FixAllState.Create(
63-
fixAllProvider, diagnosticsToFix, fixProvider, equivalenceKey);
58+
return GetFixedSolutionAsync(
59+
fixMultipleState, workspace, waitDialogTitle, waitDialogMessage, progress, cancellationToken);
60+
}
6461

65-
return GetFixedSolution(
66-
fixMultipleState, workspace, waitDialogTitle, waitDialogMessage, progress, cancellationToken);
67-
}
62+
private static async Task<Solution> GetFixedSolutionAsync(
63+
FixAllState fixAllState,
64+
Workspace workspace,
65+
string title,
66+
string waitDialogMessage,
67+
IProgress<CodeAnalysisProgress> progress,
68+
CancellationToken cancellationToken)
69+
{
70+
var fixMultipleCodeAction = new FixMultipleCodeAction(
71+
fixAllState, title, waitDialogMessage);
6872

69-
private static Solution GetFixedSolution(
70-
FixAllState fixAllState,
71-
Workspace workspace,
72-
string title,
73-
string waitDialogMessage,
74-
IProgress<CodeAnalysisProgress> progress,
75-
CancellationToken cancellationToken)
73+
Solution newSolution = null;
74+
var extensionManager = workspace.Services.GetService<IExtensionManager>();
75+
await extensionManager.PerformActionAsync(fixAllState.FixAllProvider, async () =>
7676
{
77-
var fixMultipleCodeAction = new FixMultipleCodeAction(
78-
fixAllState, title, waitDialogMessage);
79-
80-
Solution newSolution = null;
81-
var extensionManager = workspace.Services.GetService<IExtensionManager>();
82-
extensionManager.PerformAction(fixAllState.FixAllProvider, () =>
83-
{
84-
// We don't need to post process changes here as the inner code action created for Fix multiple code fix already executes.
85-
newSolution = fixMultipleCodeAction.GetChangedSolutionInternalAsync(
86-
fixAllState.Solution, progress, postProcessChanges: false, cancellationToken).WaitAndGetResult(cancellationToken);
87-
});
77+
// We don't need to post process changes here as the inner code action created for Fix multiple code fix already executes.
78+
newSolution = await fixMultipleCodeAction.GetChangedSolutionInternalAsync(
79+
fixAllState.Solution, progress, postProcessChanges: false, cancellationToken).ConfigureAwait(false);
80+
}).ConfigureAwait(false);
8881

89-
return newSolution;
90-
}
82+
return newSolution;
9183
}
9284
}

src/Features/Core/Portable/CodeFixes/FixAllOccurrences/IFixMultipleOccurrencesService.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
using System;
88
using System.Collections.Immutable;
99
using System.Threading;
10-
using Microsoft.CodeAnalysis.CodeActions;
10+
using System.Threading.Tasks;
1111
using Microsoft.CodeAnalysis.Host;
1212

1313
namespace Microsoft.CodeAnalysis.CodeFixes;
@@ -18,7 +18,7 @@ internal interface IFixMultipleOccurrencesService : IWorkspaceService
1818
/// Get the fix multiple occurrences code fix for the given diagnostics with source locations.
1919
/// NOTE: This method does not apply the fix to the workspace.
2020
/// </summary>
21-
Solution GetFix(
21+
Task<Solution> GetFixAsync(
2222
ImmutableDictionary<Document, ImmutableArray<Diagnostic>> diagnosticsToFix,
2323
Workspace workspace,
2424
CodeFixProvider fixProvider,
@@ -33,7 +33,7 @@ Solution GetFix(
3333
/// Get the fix multiple occurrences code fix for the given diagnostics with source locations.
3434
/// NOTE: This method does not apply the fix to the workspace.
3535
/// </summary>
36-
Solution GetFix(
36+
Task<Solution> GetFixAsync(
3737
ImmutableDictionary<Project, ImmutableArray<Diagnostic>> diagnosticsToFix,
3838
Workspace workspace,
3939
CodeFixProvider fixProvider,

src/VisualStudio/Core/Def/TableDataSource/Suppression/VisualStudioSuppressionFixService.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,7 @@ private async Task ApplySuppressionFixAsync(
278278
if (suppressionFixer != null)
279279
{
280280
var suppressionFixAllProvider = suppressionFixer.GetFixAllProvider();
281-
newSolution = _fixMultipleOccurencesService.GetFix(
281+
newSolution = await _fixMultipleOccurencesService.GetFixAsync(
282282
documentDiagnosticsPerLanguage,
283283
_workspace,
284284
suppressionFixer,
@@ -287,7 +287,7 @@ private async Task ApplySuppressionFixAsync(
287287
title,
288288
waitDialogMessage,
289289
progress,
290-
cancellationToken);
290+
cancellationToken).ConfigureAwait(false);
291291
if (newSolution == null)
292292
{
293293
// User cancelled or fixer threw an exception, so we just bail out.
@@ -303,7 +303,7 @@ private async Task ApplySuppressionFixAsync(
303303
if (suppressionFixer != null)
304304
{
305305
var suppressionFixAllProvider = suppressionFixer.GetFixAllProvider();
306-
newSolution = _fixMultipleOccurencesService.GetFix(
306+
newSolution = await _fixMultipleOccurencesService.GetFixAsync(
307307
projectDiagnosticsPerLanguage,
308308
_workspace,
309309
suppressionFixer,
@@ -312,7 +312,7 @@ private async Task ApplySuppressionFixAsync(
312312
title,
313313
waitDialogMessage,
314314
progress,
315-
cancellationToken);
315+
cancellationToken).ConfigureAwait(false);
316316
if (newSolution == null)
317317
{
318318
return;

0 commit comments

Comments
 (0)