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

Speed up VisualStudioProject construction #60351

Conversation

jasonmalinowski
Copy link
Member

Closes #55297

Loading these services during the VisualStudioProject constructor
means they're being loaded during the initial project creation which
is earlier than they're needed and can hold up other work. Let's not
ask for them until we actually need them.
@jasonmalinowski jasonmalinowski requested a review from a team as a code owner March 23, 2022 23:05
@jasonmalinowski jasonmalinowski self-assigned this Mar 23, 2022
@jasonmalinowski jasonmalinowski force-pushed the speed-up-visualstudioproject-construction branch from 6f978e9 to b8a6063 Compare March 23, 2022 23:30
@dotnet dotnet deleted a comment from azure-pipelines bot Mar 25, 2022
@dotnet dotnet deleted a comment from azure-pipelines bot Mar 25, 2022
@jasonmalinowski jasonmalinowski force-pushed the speed-up-visualstudioproject-construction branch from b8a6063 to e05579f Compare March 25, 2022 00:13
// task is completed, we know that the WaitUntilFullyLoadedAsync call will have actually finished and we're
// fully loaded.
var isFullyLoadedTask = workspaceStatusService?.IsFullyLoadedAsync(CancellationToken.None);
var isFullyLoaded = isFullyLoadedTask is { IsCompleted: true } && isFullyLoadedTask.GetAwaiter().GetResult();
Copy link
Member

Choose a reason for hiding this comment

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

does this .IsCompleted check actually work well? i'm worried that some part of the IsFullyLaodedAsync call is actually async (Even trivially), and we just get a task back that this is always false for.

i think i woudl like it if IsFullyLaodedAsync actually guaranteed the behavior you're looking for here by having a single task that it creates and caches and then returns to all future callers. since i think we can only fully load once... that seems viable.

Copy link
Member Author

Choose a reason for hiding this comment

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

@CyrusNajmabadi I agree the pattern isn't good, it's not new here. @sharwell might recall if we actually know if this works?

Copy link
Contributor

Choose a reason for hiding this comment

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

Original conversation where this pattern was discussed: #48215 (comment)

There is probably a question as to whether we need to maintain the telemetry here at all, given everything that has gone on since Paul originally requested it.

// After the call to EnsureDocumentOptionProvidersInitializedAsync, everything can be off the UI thread.
// Thus, we have a ConfigureAwait(false) on the call and switch explicitly after.
await _visualStudioWorkspaceImpl.EnsureDocumentOptionProvidersInitializedAsync(cancellationToken).ConfigureAwait(false);
await TaskScheduler.Default;
Copy link
Contributor

@Therzok Therzok Mar 25, 2022

Choose a reason for hiding this comment

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

Don't ConfigureAwait(false) and await TaskScheduler.Default do the same thing?

It's possible await TaskScheduler.Default is already completed so it runs synchronously, but seems redundant, maybe I'm missing something?

Copy link
Member Author

Choose a reason for hiding this comment

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

@Therzok: the .ConfigureAwait(false) only matters if the EnsureDocumentOptionProvidersInitializedAsync actually yields; if it completes synchronously we'd stay on the UI thread.

Copy link
Member Author

Choose a reason for hiding this comment

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

Which to clarify: that means we need the await TaskScheduler.Default; but as @sharwell pointed out we don't want to have the first await come to the UI thread only to immediately bounce to the UI thread, so we kinda end up with this (admittedly odd) pattern.

Copy link
Contributor

@Therzok Therzok Mar 25, 2022

Choose a reason for hiding this comment

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

That is very good to know, thank you! System.Threading.Task makes me doubt I know anything.

@jasonmalinowski jasonmalinowski merged commit 38885db into dotnet:main Mar 28, 2022
@ghost ghost added this to the Next milestone Mar 28, 2022
@jasonmalinowski jasonmalinowski deleted the speed-up-visualstudioproject-construction branch March 28, 2022 18:45
@allisonchou allisonchou modified the milestones: Next, 17.2.P3 Mar 28, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
6 participants