Skip to content

Conversation

@ToddGrun
Copy link
Contributor

This is the 2nd part of a multi-part PR series focused on improving the performance of loading the roslyn packages.

This PR focuses mostly on removing some extraneous potential thread switches.

Part 1: #77439

@ToddGrun ToddGrun requested a review from a team as a code owner March 12, 2025 17:26
@ghost ghost added Area-IDE untriaged Issues and PRs which have not yet been triaged by a lead labels Mar 12, 2025

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

Choose a reason for hiding this comment

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

InitializeAsync

Base class documents that calling it's InitializeAsync and OnAfterPackageLoadedAsync methods is not necessary.


await JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken);

_componentModel_doNotAccessDirectly = (IComponentModel?)await GetServiceAsync(typeof(SComponentModel)).ConfigureAwait(true);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

GetServiceAsync

There is no main thread requirement for getting/using this service.


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

Choose a reason for hiding this comment

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

true

no need to capture the context here as the next line will move us back to the UI thread


await JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken);

cancellationToken.ThrowIfCancellationRequested();
Copy link
Contributor Author

Choose a reason for hiding this comment

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

cancellationToken.ThrowIfCancellationRequested();

The SwitchToMainThreadAsync call captures this check


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

Choose a reason for hiding this comment

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

true

No need to ensure we're on the captured context if the next line moves us to the main thread.

try
{
await base.InitializeAsync(cancellationToken, progress).ConfigureAwait(true);
await JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

SwitchToMainThreadAsync

RegisterService doesn't require main thread

Copy link
Member

Choose a reason for hiding this comment

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

do we need/want CA(true) on the prior line? if so, doc.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

no, we don't want that either, I just missed it in this PR. I'll go ahead and change.

Copy link
Member

Choose a reason for hiding this comment

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

doc that as well plz

Protected Overrides Async Function InitializeAsync(cancellationToken As CancellationToken, progress As IProgress(Of ServiceProgressData)) As Task
Try
Await MyBase.InitializeAsync(cancellationToken, progress).ConfigureAwait(True)
Await JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

SwitchToMainThreadAsync

Neither RegisterLanguageService nor RegisterService require the main thread.

Copy link
Member

Choose a reason for hiding this comment

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

do we need/want CA(true) on the prior line? if so, doc.

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.

signing off. but i think it wouild be good for these critical sections to doc the intentional behavior here.

@ToddGrun
Copy link
Contributor Author

i think it wouild be good for these critical sections to doc the intentional behavior here.

Agreed, I will add some documentation once things get a little closer to the end target.

_componentModel_doNotAccessDirectly = (IComponentModel?)await GetServiceAsync(typeof(SComponentModel)).ConfigureAwait(true);
_componentModel_doNotAccessDirectly = (IComponentModel?)await GetServiceAsync(typeof(SComponentModel)).ConfigureAwait(false);
Assumes.Present(_componentModel_doNotAccessDirectly);

Copy link
Member

Choose a reason for hiding this comment

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

nit: feel free to do in a follow up

Suggested change

Copy link
Contributor Author

Choose a reason for hiding this comment

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

whoops! I had a whole bunch of logging that I was using for local verification, and looks like I didn't remove the newline that I had next to it.

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.

3 participants