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

[Responsiveness] Roslyn initialization is forced onto the UI thread, forcing the project system to synchronize initialize it (6.9% of solution open) #55297

Closed
davkean opened this issue Aug 11, 2016 · 36 comments · Fixed by dotnet/project-system#6979 or #60351

Comments

@davkean
Copy link
Member

davkean commented Aug 11, 2016

IWorkspaceProjectContextFactory.CreateProjectContextAsync is forced on the UI thread via Roslyn during solution load. UI thread is scarce resource during solution load and this means that Roslyn is prevented from being initialized until each project synchronously blocks on it in PrioritizedOnAfterOpenProject.

The project system would like to overlap this initialization so that we can make use of as many cores as possible during load.

@davkean
Copy link
Member Author

davkean commented Sep 15, 2016

We cannot do this, until we've fixed the race in dotnet/project-system#485.

@mavasani
Copy link
Contributor

This is now blocked by #15871

@Pilchie
Copy link
Member

Pilchie commented Dec 19, 2017

Taking this, since @jasonmalinowski's work will likely not be ready before @davkean is out.

@Pilchie Pilchie assigned Pilchie and unassigned davkean Dec 19, 2017
@Pilchie
Copy link
Member

Pilchie commented Jan 18, 2018

Moving to 15.7, since this work is risky and we'll try to tackle this early in 15.7.

@davkean
Copy link
Member Author

davkean commented Nov 7, 2018

Everything but creation is thread-safe and thread-agnostic.

@davkean
Copy link
Member Author

davkean commented Nov 7, 2018

We have done this for population and dispose (dotnet/project-system#4229), and just waiting on creation. We are blocked on Roslyn making a change around this.

@davkean
Copy link
Member Author

davkean commented Nov 7, 2018

Dispose isn't free-threaded, so backed that out: dotnet/project-system#4234

    Microsoft.CodeAnalysis.Workspaces.dll!Roslyn.Utilities.Contract.ThrowIfFalse(bool condition, string message)    Unknown
    Microsoft.CodeAnalysis.EditorFeatures.dll!Microsoft.CodeAnalysis.Editor.Shared.Utilities.ForegroundThreadAffinitizedObject.AssertIsForeground()    Unknown
    Microsoft.VisualStudio.LanguageServices.dll!Microsoft.VisualStudio.LanguageServices.Implementation.ProjectSystem.VisualStudioWorkspaceImpl.SetDocumentContext(Microsoft.CodeAnalysis.DocumentId documentId)    Unknown
    Microsoft.CodeAnalysis.Workspaces.dll!Microsoft.CodeAnalysis.Workspace.ClearOpenDocument(Microsoft.CodeAnalysis.DocumentId documentId, bool isSolutionClosing)    Unknown
    Microsoft.CodeAnalysis.Workspaces.dll!Microsoft.CodeAnalysis.Workspace.ClearOpenDocuments(Microsoft.CodeAnalysis.ProjectId projectId)    Unknown
    Microsoft.CodeAnalysis.Workspaces.dll!Microsoft.CodeAnalysis.Workspace.ClearProjectData(Microsoft.CodeAnalysis.ProjectId projectId)    Unknown
    Microsoft.CodeAnalysis.Workspaces.dll!Microsoft.CodeAnalysis.Workspace.OnProjectRemoved(Microsoft.CodeAnalysis.ProjectId projectId)    Unknown
    Microsoft.VisualStudio.LanguageServices.dll!Microsoft.VisualStudio.LanguageServices.Implementation.ProjectSystem.VisualStudioWorkspaceImpl.OnProjectRemoved(Microsoft.CodeAnalysis.ProjectId projectId)    Unknown
    Microsoft.VisualStudio.LanguageServices.dll!Microsoft.VisualStudio.LanguageServices.Implementation.ProjectSystem.VisualStudioProject.RemoveFromWorkspace.AnonymousMethod__86_0(Microsoft.CodeAnalysis.Workspace w)    Unknown
    Microsoft.VisualStudio.LanguageServices.dll!Microsoft.VisualStudio.LanguageServices.Implementation.ProjectSystem.VisualStudioWorkspaceImpl.ApplyChangeToWorkspace(System.Action<Microsoft.CodeAnalysis.Workspace> action)    Unknown
    Microsoft.VisualStudio.LanguageServices.dll!Microsoft.VisualStudio.LanguageServices.Implementation.ProjectSystem.VisualStudioProject.RemoveFromWorkspace()    Unknown
    Microsoft.VisualStudio.LanguageServices.Implementation.dll!Microsoft.VisualStudio.LanguageServices.Implementation.ProjectSystem.CPS.CPSProject.Dispose()    Unknown

@drewnoakes
Copy link
Member

drewnoakes commented Feb 1, 2021

We still have two instances of switching to the UI thread in WorkspaceProjectContextProvider that reference this issue. Re-opening.

@drewnoakes drewnoakes reopened this Feb 1, 2021
@tmeschter
Copy link
Contributor

@drewnoakes Is the work solely on our side, or do we need something further from Roslyn to eliminate those last two places we switch to the UI thread?

@davkean
Copy link
Member Author

davkean commented Feb 2, 2021 via email

@drewnoakes
Copy link
Member

Filed #51016 to track the Roslyn side of this work.

@drewnoakes drewnoakes self-assigned this Feb 5, 2021
@drewnoakes
Copy link
Member

dotnet/project-system#6953 removes one of the two UI switches.

@drewnoakes
Copy link
Member

#51138 is the Roslyn-side of the other UI switch.

@CyrusNajmabadi
Copy link
Member

The roslyn side of this is complete. You can go ahead with this @drewnoakes

@drewnoakes
Copy link
Member

Thanks @CyrusNajmabadi. I'll pick this up once an updated version of the Microsoft.VisualStudio.LanguageServices package is available. The latest seems to be from 8 days ago, unless I'm looking at the wrong feed.

@drewnoakes

This comment has been minimized.

drewnoakes referenced this issue in drewnoakes/project-system Feb 21, 2021
Fixes #353

Roslyn recently implemented a free-threaded version of this API, meaning we no longer need to switch to the UI thread before calling it.

This commit bumps the package version, removes the thread switch and calls the new API.
drewnoakes referenced this issue in drewnoakes/project-system Feb 22, 2021
Fixes #353

Roslyn recently implemented a free-threaded version of this API, meaning we no longer need to switch to the UI thread before calling it.

This commit bumps the package version, removes the thread switch and calls the new API.
drewnoakes referenced this issue in drewnoakes/project-system Feb 22, 2021
Fixes #353

Roslyn recently implemented a free-threaded version of this API, meaning we no longer need to switch to the UI thread before calling it.

This commit bumps the package version, removes the thread switch and calls the new API.
@drewnoakes
Copy link
Member

Re-opening. Roslyn made changes to support this, but it introduced DDRIT failures.

cc @jasonmalinowski @CyrusNajmabadi

davkean referenced this issue in davkean/project-system Jul 30, 2021
Fixes: .NET Project System's side of https://github.com/dotnet/project-system/issues/353.

Roslyn already immediately switches to the UI thread CreateProjectContextAsync, so this should be a no-op. However, this enables the above bug to be moved over to Roslyn and for them to remove the UI thread dependency in the future.
davkean referenced this issue in davkean/project-system Jul 30, 2021
Fixes: .NET Project System's side of https://github.com/dotnet/project-system/issues/353.

Roslyn already immediately switches to the UI thread CreateProjectContextAsync, so this should be a no-op. However, this enables the above bug to be moved over to Roslyn and for them to remove the UI thread dependency in the future.
@CyrusNajmabadi
Copy link
Member

That seems reasonable. Though i think @jasonmalinowski will need to be pulled on this. He has the most context on why parts of our PS impl are UI thread affinitized. I have no doubt we can get (almost) everything off the UI thread, but he'll be the best at just knowing the places that are currently problematic.

@davkean davkean transferred this issue from dotnet/project-system Jul 30, 2021
@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 30, 2021
@davkean davkean changed the title [Responsiveness] Remove language service "switch to UI thread" when Roslyn interaction is thread-safe (6.9% of solution open) [Responsiveness] Roslyn initialization is forced onto the UI thread, forcing the project system to synchronize initialize it (6.9% of solution open) Jul 30, 2021
@davkean
Copy link
Member Author

davkean commented Jul 30, 2021

I've moved it over, the project system change has been merged in.

@jinujoseph jinujoseph added Area-Performance and removed untriaged Issues and PRs which have not yet been triaged by a lead labels Jul 31, 2021
@jinujoseph jinujoseph added this to the 17.0 milestone Jul 31, 2021
@jasonmalinowski
Copy link
Member

@CyrusNajmabadi @davkean I'm confused for what the remaining asks are here for this bug. It looks like @drewnoakes reactivated it when @CyrusNajmabadi's fix had DDRIT failures, but it seems all the changes have now gone in?

@davkean
Copy link
Member Author

davkean commented Sep 13, 2021

Project System removed their switch but this path still immediately switches to the UI thread, blocking it and preventing other things from progressing and overlapping.

@jasonmalinowski jasonmalinowski modified the milestones: 17.0, 17.1 Sep 14, 2021
@CyrusNajmabadi
Copy link
Member

Yes. The only work we did was to enable this to be called asynchronously from any thread. We didn't do anything on our end to make things better on the UI thread.

@jasonmalinowski jasonmalinowski modified the milestones: 17.1, 17.2 Jan 5, 2022
@jasonmalinowski
Copy link
Member

@drewnoakes I think we can close this at this point, or do you still have a UI thread switch before calling into Roslyn somewhere?

@davkean
Copy link
Member Author

davkean commented Mar 22, 2022

@jasonmalinowski This is representing the time Roslyn spends on the UI thread, last I saw in some traces, this was up to 30%. This isn't resolved.

@jasonmalinowski
Copy link
Member

@davkean Can you share the trace then?

@jasonmalinowski
Copy link
Member

@davkean Also to be clear I'm using this bug to track the original request which was making the project initialization path moved off the UI thread which is now as far as it can go without having shell APIs changed; if there's other paths that aren't that, we should have bugs for those, but let's have new bugs for those.

@davkean
Copy link
Member Author

davkean commented Mar 22, 2022

@jasonmalinowski I filed the original bug, and its always been about Roslyn chewing the UI thread.

All Orchard Core traces are showing this. Here's from yesterday's build from a cached load:

image

If you believe that Roslyn are unable to address these, then dupe these against the shell bugs we've filed. Looking at the trace, I see that Roslyn forces the editor package to be initialized on the UI thread, which is not helping. This is editor's fault.

@jasonmalinowski
Copy link
Member

@davkean Alright, we can take a look at fixing that, thanks for the info!

@jasonmalinowski
Copy link
Member

(and indeed that's a different stack than I've seen be expensive before...)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment