Replace install render timer with dispatcher callbacks

This commit is contained in:
Chris Titus
2026-07-01 22:55:35 -05:00
parent 6b2ecf5b76
commit afd0a36003
2 changed files with 35 additions and 32 deletions
@@ -13,6 +13,28 @@ function Invoke-WinUtilInstallAppRenderBatch {
}
}
function Complete-WinUtilInstallAppRendering {
$sync.InstallAppEntriesRendered = $true
Write-WinUtilPerformanceCheckpoint -Name "Install app entries rendered"
}
function Invoke-WinUtilInstallAppRenderNextBatch {
if ($sync.InstallAppRenderQueue.Count -gt 0) {
$categoryBatch = $sync.InstallAppRenderQueue.Dequeue()
Invoke-WinUtilInstallAppRenderBatch -CategoryBatch $categoryBatch
}
if ($sync.InstallAppRenderQueue.Count -gt 0) {
$sync.Form.Dispatcher.BeginInvoke(
[System.Windows.Threading.DispatcherPriority]::Background,
[action]{ Invoke-WinUtilInstallAppRenderNextBatch }
) | Out-Null
return
}
Complete-WinUtilInstallAppRendering
}
function Start-WinUtilInstallAppRendering {
if ($null -eq $sync.InstallAppRenderQueue) {
return
@@ -20,30 +42,11 @@ function Start-WinUtilInstallAppRendering {
$sync.InstallAppEntriesRendered = $false
if ($sync.Form -and $sync.Form.Dispatcher -and ("System.Windows.Threading.DispatcherTimer" -as [type])) {
$timer = New-Object System.Windows.Threading.DispatcherTimer
$timer.Interval = [TimeSpan]::FromMilliseconds(1)
$timer.Add_Tick({
param($sender)
$dispatcherTimer = [System.Windows.Threading.DispatcherTimer]$sender
$dispatcherTimer.Stop()
if ($sync.InstallAppRenderQueue.Count -gt 0) {
$categoryBatch = $sync.InstallAppRenderQueue.Dequeue()
Invoke-WinUtilInstallAppRenderBatch -CategoryBatch $categoryBatch
}
if ($sync.InstallAppRenderQueue.Count -gt 0) {
$dispatcherTimer.Start()
return
}
$sync.InstallAppEntriesRendered = $true
Write-WinUtilPerformanceCheckpoint -Name "Install app entries rendered"
})
$sync.InstallAppRenderTimer = $timer
$timer.Start()
if ($sync.Form -and $sync.Form.Dispatcher) {
$sync.Form.Dispatcher.BeginInvoke(
[System.Windows.Threading.DispatcherPriority]::Background,
[action]{ Invoke-WinUtilInstallAppRenderNextBatch }
) | Out-Null
return
}
@@ -52,6 +55,5 @@ function Start-WinUtilInstallAppRendering {
Invoke-WinUtilInstallAppRenderBatch -CategoryBatch $categoryBatch
}
$sync.InstallAppEntriesRendered = $true
Write-WinUtilPerformanceCheckpoint -Name "Install app entries rendered"
Complete-WinUtilInstallAppRendering
}
+7 -6
View File
@@ -15,21 +15,22 @@ Describe "Install app rendering startup contract" {
$categoryScript | Should -Match 'Pre-group apps by category before creating WPF controls'
}
It "renders queued apps through a dispatcher timer when a form dispatcher exists" {
It "renders queued apps through dispatcher callbacks when a form dispatcher exists" {
$renderScript = Get-Content -Path (Join-Path $script:repoRoot "functions\private\Start-WinUtilInstallAppRendering.ps1") -Raw
$renderScript | Should -Match 'System\.Windows\.Threading\.DispatcherTimer'
$renderScript | Should -Match 'Dispatcher\.BeginInvoke'
$renderScript | Should -Match 'Invoke-WinUtilInstallAppRenderNextBatch'
$renderScript | Should -Match 'Initialize-InstallAppEntry'
$renderScript | Should -Match 'Install app entries rendered'
}
It "does not rely on local timer variables after the dispatcher tick fires" {
It "does not use dispatcher timers for deferred install rendering" {
$renderScript = Get-Content -Path (Join-Path $script:repoRoot "functions\private\Start-WinUtilInstallAppRendering.ps1") -Raw
$renderScript | Should -Match 'param\(\$sender\)'
$renderScript | Should -Match '\$dispatcherTimer = \[System\.Windows\.Threading\.DispatcherTimer\]\$sender'
$renderScript | Should -Not -Match 'DispatcherTimer'
$renderScript | Should -Not -Match '\$timer'
$renderScript | Should -Not -Match '\$dispatcherTimer'
$renderScript | Should -Not -Match '\$timer\.Stop\(\)'
$renderScript | Should -Match '\$dispatcherTimer\.Start\(\)'
$renderScript | Should -Not -Match '& \$renderCategory'
}