Speed up runspace and tab initialization (#4793)

* Add startup performance tracing

* Lazy initialize non-default tabs

* Render install app entries incrementally

* Defer and cache toggle status checks

* Clean up runspace invocation ownership

* Defer GUI runspace pool startup

* Defer status taskbar asset rendering

* Record final speed verification

* Fix deferred install render timer callback

* Add dispatcher smoke coverage for install rendering

* Replace install render timer with dispatcher callbacks

* Gate performance tracing behind compile switch

* Clean up analyzer warnings in speed changes

* Speed up runspace and tab initialization
This commit is contained in:
Chris Titus
2026-07-01 23:34:59 -05:00
committed by GitHub
parent 916dc761ba
commit 93dc23dd66
31 changed files with 1114 additions and 133 deletions
+51 -14
View File
@@ -30,30 +30,67 @@ function Invoke-WPFRunspace {
$ParameterList
)
if (-not ("WinUtilRunspaceCleanup" -as [type])) {
Add-Type @"
using System;
using System.Management.Automation;
public sealed class WinUtilRunspaceCleanupState
{
public PowerShell PowerShell { get; set; }
public IAsyncResult Handle { get; set; }
}
public static class WinUtilRunspaceCleanup
{
public static void Cleanup(object state, bool timedOut)
{
var cleanupState = state as WinUtilRunspaceCleanupState;
if (cleanupState == null || cleanupState.PowerShell == null || cleanupState.Handle == null)
{
return;
}
try
{
cleanupState.PowerShell.EndInvoke(cleanupState.Handle);
}
catch
{
}
finally
{
cleanupState.PowerShell.Dispose();
}
}
}
"@
}
Initialize-WinUtilRunspacePool | Out-Null
# Create a PowerShell instance
$script:powershell = [powershell]::Create()
$powershell = [powershell]::Create()
# Add Scriptblock and Arguments to runspace
[void]$script:powershell.AddScript($ScriptBlock)
[void]$script:powershell.AddArgument($ArgumentList)
[void]$powershell.AddScript($ScriptBlock)
[void]$powershell.AddArgument($ArgumentList)
foreach ($parameter in $ParameterList) {
[void]$script:powershell.AddParameter($parameter[0], $parameter[1])
[void]$powershell.AddParameter($parameter[0], $parameter[1])
}
$script:powershell.RunspacePool = $sync.runspace
$powershell.RunspacePool = $sync.runspace
# Execute the RunspacePool
$script:handle = $script:powershell.BeginInvoke()
$handle = $powershell.BeginInvoke()
$cleanupState = [WinUtilRunspaceCleanupState]::new()
$cleanupState.PowerShell = $powershell
$cleanupState.Handle = $handle
$cleanupCallback = [System.Threading.WaitOrTimerCallback][WinUtilRunspaceCleanup]::Cleanup
[System.Threading.ThreadPool]::RegisterWaitForSingleObject($handle.AsyncWaitHandle, $cleanupCallback, $cleanupState, -1, $true) | Out-Null
# Clean up the RunspacePool threads when they are complete, and invoke the garbage collector to clean up the memory
if ($script:handle.IsCompleted) {
$script:powershell.EndInvoke($script:handle)
$script:powershell.Dispose()
$sync.runspace.Dispose()
$sync.runspace.Close()
[System.GC]::Collect()
}
# Return the handle
return $handle
}
+1
View File
@@ -29,6 +29,7 @@ function Invoke-WPFTab {
}
}
$sync.currentTab = $sync.$tabNav.Items[$tabNumber].Header
Initialize-WinUtilTabContent -TabName $sync.currentTab
# Always reset the filter for the current tab
if ($sync.currentTab -eq "Install") {