Skip to content

Remove RoslynServiceExtensions.GetServiceAsync #77799

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Conversation

ToddGrun
Copy link
Contributor

Fixes #73636

Remove the RoslynServiceExtensions.GetServiceAsync and instead encourage use of the standard IAsyncServiceProvider* methods. The VS implementation of these methods has been changed to better understand which interfaces require a main thread switch for the cast, as opposed to the roslyn implementations which blindly did a main thread switch.

Fixes dotnet#73636

Remove the RoslynServiceExtensions.GetServiceAsync and instead encourage use of the standard IAsyncServiceProvider* methods. The VS implementation of these methods has been changed to better understand which interfaces require a main thread switch for the cast, as opposed to the roslyn implementations which blindly did a main thread switch.
@ToddGrun ToddGrun requested review from a team as code owners March 25, 2025 03:56
@ghost ghost added Area-IDE untriaged Issues and PRs which have not yet been triaged by a lead labels Mar 25, 2025
Comment on lines 27 to 28
M:Microsoft.VisualStudio.Shell.ServiceExtensions.GetService``2(System.IServiceProvider); Use RoslynServiceExtensions instead. This extension internally relies on ThreadHelper, which is incompatible with testing.
M:Microsoft.VisualStudio.Shell.ServiceExtensions.GetService``2(System.IServiceProvider,System.Boolean); Use RoslynServiceExtensions instead. This extension internally relies on ThreadHelper, which is incompatible with testing
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should these be banned too, or the message updated for it?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't look into these methods, so I'd rather not remove or change their message

Copy link
Member

@jasonmalinowski jasonmalinowski left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And There Was Much Rejoicing

@@ -34,7 +34,7 @@ public StubVsServiceExporter(
[Import(typeof(SAsyncServiceProvider))] IAsyncServiceProvider2 asyncServiceProvider,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@davkean's bug specifically calls out IAsyncServiceProvider3, do we need to move to those newer interface here or are we good? His comment makes me think all the methods will eventually call the right thing.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My understanding is that the implementations on each of the interfaces will do the right thing, and that there is no need to explicitly use the "3" interface.

await _threadingContext.JoinableTaskFactory.SwitchToMainThreadAsync(_threadingContext.DisposalToken);
shellService.AdviseSolutionEvents(this, out _);
shellService!.AdviseSolutionEvents(this, out _);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if we should be putting the ! on the fetching so that way the nullable suppression is closer to the place where the throwOnFailure: true is. Or it's unfortunate if we can't get that nullable annotated in some way to make this simpler.

Copy link
Contributor Author

@ToddGrun ToddGrun Mar 25, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like there is a version of GetServiceAsync that only takes in a CancellationToken and assumes throwOnFailure is true and has null annotated the return values. Switched over to use that when possible.

…ust takes in a CancellationToken as that is nullable annotated to indicate the return value isn't null
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area-IDE untriaged Issues and PRs which have not yet been triaged by a lead
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants