Skip to content

Join tasks waited by JoinableTaskCollection.JoinUntilEmpty in dumpasync result#1538

Open
lifengl wants to merge 4 commits intomainfrom
dev/lifengl/handleJoinTillEmptyAsync
Open

Join tasks waited by JoinableTaskCollection.JoinUntilEmpty in dumpasync result#1538
lifengl wants to merge 4 commits intomainfrom
dev/lifengl/handleJoinTillEmptyAsync

Conversation

@lifengl
Copy link
Member

@lifengl lifengl commented Feb 9, 2026

This PR is to join waiting tasks in the JoinableTaskCollection case. It appears that it is quite common in closing IDE hangs, and quite some developers struggle to find out what is inside the collection. Those steps are often done through some unreliable manual step works depending on the initialDelegate of the JTF task, which sometime doesn't work well when it points some JIT stubs.

This PR is to fix (at least in some cases based on dumps I got) and join the task chain in that case. It also fixes some missing indication that a task is blocking the main thread, when the main thread has several nested JTF.Run. (I guess it is better to nested them in the task chain, which I will follow up on that.

Hopefully, it can save some time in some deadlock investigation sessions.

A sample looks like this. Before this PR, the JoinTillEmptyAsync and BuildAsync will be seperated, and SynchouslyBlockingMainThread is missing due to the logic only marks on JTF.Run inside the solution code. The project JTF is nested inside that one.

21d6d12fed0 <2> Microsoft.VisualStudio.ProjectServices.DesignTimeBuilder+<BuildAsync>d__21 @ 7ffa1f447c60
..21ce6d4a0a0 <1> * Microsoft.VisualStudio.ProjectSystem.VS.Implementation.Build.DesignTimeBuilderService+BuilderLifetimeHelper+<>c__DisplayClass16_0+<<BuildAsync>b__0>d @ 7ffa2aeabe70
..21ce388b430 <0> Microsoft.VisualStudio.Threading.JoinableTaskCollection+<JoinTillEmptyAsync>d__20 @ 7ffa518e5130
..21ce388b8c8 <1> Microsoft.VisualStudio.ProjectSystem.VS.Implementation.Build.DesignTimeBuilderService+BuilderLifetimeHelper+<CloseAsync>d__17 @ 7ffa2aea9d10
..21d2af733f8 <1> Microsoft.VisualStudio.ProjectSystem.VS.Implementation.Build.DesignTimeBuilderService+<>c__DisplayClass26_0+<<BeforeCloseSolutionAsync>b__0>d @ 7ffa2a3e9790
..21cea1de508 <0> Microsoft.VisualStudio.Threading.TplExtensions+<InvokeAsync>d__19 @ 7ffa518e5cc0
..21cea1de818 <1> Microsoft.VisualStudio.ProjectSystem.UnconfiguredProjectImpl+<SaveStatesAsync>d__244 @ 7ffa28b18220
..21cea1deaa0 <1> Microsoft.VisualStudio.ProjectSystem.UnconfiguredProjectImpl+<DisposeAsync>d__222 @ 7ffa28b15d00
..21cea1ded68 <1> Microsoft.VisualStudio.ProjectSystem.ProjectServiceHost+<UnloadProjectAsync>d__80 @ 7ffa28b14fd0
..21cea1df008 <2> Microsoft.VisualStudio.ProjectSystem.VS.Implementation.Package.ProjectNode+<<Close>b__461_1>d @ 7ffa2a3ec360
-- Thread TID:[9668] - JoinableTask: 21cea1ddb10 SynchronouslyBlockingMainThread

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Updates !DumpAsync analysis to better surface JoinableTask dependencies when a JoinableTaskCollection.JoinTillEmptyAsync-style state machine is involved, and to improve identification of main-thread blocking scenarios in nested JTF runs.

Changes:

  • Extracts joined tasks from JoinableTaskCollection.dependentData.childDependentNodes and attaches them to the corresponding async state machine.
  • Extends joinable-task chaining logic to also consider tasks found via a JoinableTaskCollection.
  • Adjusts blocking-task discovery to continue scanning for additional blocking joinable tasks on the same thread; tweaks output spacing behavior.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant