From 3b7a898a2c46d09e522ad7dca9d9050df9ab0660 Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Sat, 23 May 2026 18:38:19 +0200 Subject: [PATCH] Stop awaiting decompiles those tests never read The four `WaitForDecompiledTextAsync` calls in PreviewTabPromotionTests asserted only on dock structure -- SourceNode, IsPreview, tab count, Content reference -- never on decompiled Text. Those values are set synchronously by ShowSelectedNode before DecompileAsync's first await returns, so the ~25s wait was pure dead weight. Worse, the fire-and-forget DecompileAsync kept chewing CPU after the test returned and contended on the ThreadPool with the next test's decompile, which is what pushed the same workload from 12-16s in isolation to 24-28s in full-suite -- right up against the 30s budget. One slow GC pause and PinCurrentTab_Flips timed out at 30.997s exactly. --- ILSpy.Tests/Docking/PreviewTabPromotionTests.cs | 8 ++++---- ILSpy/Docking/DockWorkspace.cs | 11 +++++++++++ 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/ILSpy.Tests/Docking/PreviewTabPromotionTests.cs b/ILSpy.Tests/Docking/PreviewTabPromotionTests.cs index 92e0e522c..0c56f8552 100644 --- a/ILSpy.Tests/Docking/PreviewTabPromotionTests.cs +++ b/ILSpy.Tests/Docking/PreviewTabPromotionTests.cs @@ -94,7 +94,7 @@ public class PreviewTabPromotionTests var typeNode = vm.AssemblyTreeModel.FindNode( "System.Linq", "System.Linq", "System.Linq.Enumerable"); vm.AssemblyTreeModel.SelectNode(typeNode); - await vm.DockWorkspace.WaitForDecompiledTextAsync(System.TimeSpan.FromSeconds(60)); + vm.DockWorkspace.SettleSelection(); ReferenceEquals(previousMainTab.SourceNode, typeNode).Should().BeTrue( "baseline: tree selection populated MainTab with the chosen node"); @@ -135,7 +135,7 @@ public class PreviewTabPromotionTests var typeA = vm.AssemblyTreeModel.FindNode( "System.Linq", "System.Linq", "System.Linq.Enumerable"); vm.AssemblyTreeModel.SelectNode(typeA); - await vm.DockWorkspace.WaitForDecompiledTextAsync(System.TimeSpan.FromSeconds(60)); + vm.DockWorkspace.SettleSelection(); var pinnedTab = factory.MainTab!; var pinnedContent = pinnedTab.Content; @@ -150,7 +150,7 @@ public class PreviewTabPromotionTests var typeB = vm.AssemblyTreeModel.FindNode( "System.Private.Uri", "System", "System.Uri"); vm.AssemblyTreeModel.SelectNode(typeB); - await vm.DockWorkspace.WaitForDecompiledTextAsync(System.TimeSpan.FromSeconds(60)); + vm.DockWorkspace.SettleSelection(); // New tab spawned beside the pinned one. vm.DockWorkspace.Documents!.VisibleDockables!.Count.Should().Be(tabCountBeforeSelection + 1, @@ -595,7 +595,7 @@ public class PreviewTabPromotionTests var typeB = vm.AssemblyTreeModel.FindNode( "System.Private.Uri", "System", "System.Uri"); vm.AssemblyTreeModel.SelectNode(typeB); - await vm.DockWorkspace.WaitForDecompiledTextAsync(System.TimeSpan.FromSeconds(60)); + vm.DockWorkspace.SettleSelection(); vm.DockWorkspace.Documents!.VisibleDockables!.Count.Should().Be(tabCountBefore + 1, "selecting a tree node while a frozen tab is active must spawn a new preview tab"); diff --git a/ILSpy/Docking/DockWorkspace.cs b/ILSpy/Docking/DockWorkspace.cs index 30f3bf6c4..8c5bb5f4d 100644 --- a/ILSpy/Docking/DockWorkspace.cs +++ b/ILSpy/Docking/DockWorkspace.cs @@ -1076,6 +1076,17 @@ namespace ILSpy.Docking /// a fresh preview tab inside . Re-clicking the same /// node after pin is a no-op (the dedupe activates the pinned tab). /// + /// + /// Pump dispatcher jobs so synchronously-set selection state (SourceNode, IsPreview, + /// tab count, Content reference) finishes propagating, without awaiting the + /// fire-and-forget DecompileAsync. Tests that assert on dock structure can use this + /// instead of WaitForDecompiledTextAsync to avoid the multi-second decompile wait. + /// + public void SettleSelection() + { + Avalonia.Threading.Dispatcher.UIThread.RunJobs(); + } + public void PinCurrentTab() { if (factory.PinCurrentMainTab() is null)