Skip to content
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

Reduce Roslyn packages impact on UI thread #74501

Open
wants to merge 6 commits into
base: main
Choose a base branch
from

Conversation

davkean
Copy link
Member

@davkean davkean commented Jul 23, 2024

Based on our UI and hang data, Roslyn's packages are one the most expensive packages during solution load. This is an attempt at moving as much as posssible of the Roslyn packages to a background thread, removing unnecessarily UI thread dependencies. This is entirely untested - and I expect to run this through a full insertion before merge.

davkean added 6 commits July 23, 2024 23:10
AsyncPackage does not need to be called as called out by the documentation.
GetServiceAsync doesn't need the UI thread, and neither does the cast to IComponentModel. I would have switched this to GetServiceAsync<TService, TInterface> which will do the right thing, but that is banned in this repository.
RegisterLanguageService and RegisterService do not require the UI thread.
SwitchToMainThreadAync will throw if its cancelled when it resumes.
All of these actions have no UI thread affinity based on inspection.
@davkean davkean requested a review from a team as a code owner July 23, 2024 14:32
@dotnet-issue-labeler dotnet-issue-labeler bot added Area-IDE untriaged Issues and PRs which have not yet been triaged by a lead labels Jul 23, 2024
@dotnet-policy-service dotnet-policy-service bot added the Community The pull request was submitted by a contributor who is not a Microsoft employee. label Jul 23, 2024
Copy link
Member

@CyrusNajmabadi CyrusNajmabadi left a comment

Choose a reason for hiding this comment

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

lgtm, but want jason/sam eyes.

@@ -27,10 +27,6 @@ internal IComponentModel ComponentModel

protected override async Task InitializeAsync(CancellationToken cancellationToken, IProgress<ServiceProgressData> progress)
{
await base.InitializeAsync(cancellationToken, progress).ConfigureAwait(true);
Copy link
Member

Choose a reason for hiding this comment

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

is it ok/intentional to not cal the base here? i'd actually like a comment saying that thsi is intentional, so it doesn't come backk in the future.

Copy link
Member Author

Choose a reason for hiding this comment

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

We could doc it if you want, but no package in VS calls InitializeAsync anymore. I've documented this.

Copy link
Member

Choose a reason for hiding this comment

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

doc'ing would def be nice. just so we have smething to state that this is very intentional as opposed to accidental.


var shell = (IVsShell7)await GetServiceAsync(typeof(SVsShell)).ConfigureAwait(true);
cancellationToken.ThrowIfCancellationRequested();
Assumes.Present(shell);
Copy link
Member

Choose a reason for hiding this comment

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

could this move below the foreach? is that beneficial? my thinking is smiply that we don't acutaly need this service until later, so why not delay till then?

Copy link
Member Author

Choose a reason for hiding this comment

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

It can, there is no benefit to it being here. This is effectively a synchronous call anyway because SVsShell is always existing sync service, it never yields.

Copy link
Member Author

@davkean davkean Jul 24, 2024

Choose a reason for hiding this comment

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

Because Roslyn has their own version of these extensions, I would love to be able to replace all three lines with just the following but I can't until its "unbanned":.

var shell = this.GetServiceAsync<SVsShell, IVsShell>(cancellationToken)

@CyrusNajmabadi
Copy link
Member

@jasonmalinowski @sharwell @ToddGrun ptal. These PRs are very relevant for helping with VS startup time. Let's work fast to unblock dave.

await JoinableTaskFactory.SwitchToMainThreadAsync(ct);
return new TempPECompilerService(workspace.Services.GetService<IMetadataService>());
return new TempPECompilerService(metadataService);
Copy link
Contributor

Choose a reason for hiding this comment

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

TempPECompilerService

Does this ctor really need to be called on the main thread?

Copy link
Contributor

Choose a reason for hiding this comment

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

(Same question applies for the VisualBasicPackage.InitializeAsync)

Copy link
Contributor

Choose a reason for hiding this comment

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

Tagging @davkean just to make sure this question has been seen

Copy link
Member Author

Choose a reason for hiding this comment

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

No it does not.

@davkean
Copy link
Member Author

davkean commented Jul 31, 2024

Sorry folks, I'll need to get back to this next week, I haven't tested this and this clearly has fallout so need to spend time understanding the ramifications.

@jasonmalinowski
Copy link
Member

@davkean Is this still needing reviews or needing some more engineering work?

@davkean
Copy link
Member Author

davkean commented Jan 16, 2025

This really needs someone familar with the code to pick up, and treat my PR as a proposal. We can close this for now, but this will become an ask this quarter as we start focusing on startup scenarios.

@CyrusNajmabadi
Copy link
Member

@sharwell could you please help with this?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area-IDE Community The pull request was submitted by a contributor who is not a Microsoft employee. 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.

5 participants