mirror of
https://github.com/Raphire/Win11Debloat.git
synced 2026-04-03 14:06:27 +00:00
Improve app page with sorting, recommendations and more (#520)
This commit is contained in:
16
Scripts/Threading/DoEvents.ps1
Normal file
16
Scripts/Threading/DoEvents.ps1
Normal file
@@ -0,0 +1,16 @@
|
||||
# Processes all pending WPF window messages (input, render, etc.) to keep the UI responsive
|
||||
# during long-running operations on the UI thread. Equivalent to Application.DoEvents().
|
||||
function DoEvents {
|
||||
if (-not $script:GuiWindow) { return }
|
||||
$frame = [System.Windows.Threading.DispatcherFrame]::new()
|
||||
$null = [System.Windows.Threading.Dispatcher]::CurrentDispatcher.BeginInvoke(
|
||||
[System.Windows.Threading.DispatcherPriority]::Background,
|
||||
[System.Windows.Threading.DispatcherOperationCallback]{
|
||||
param($f)
|
||||
$f.Continue = $false
|
||||
return $null
|
||||
},
|
||||
$frame
|
||||
)
|
||||
$null = [System.Windows.Threading.Dispatcher]::PushFrame($frame)
|
||||
}
|
||||
55
Scripts/Threading/Invoke-NonBlocking.ps1
Normal file
55
Scripts/Threading/Invoke-NonBlocking.ps1
Normal file
@@ -0,0 +1,55 @@
|
||||
# Runs a scriptblock in a background PowerShell runspace while keeping the UI responsive.
|
||||
# In GUI mode, the work executes on a separate thread and the UI thread pumps messages (~60fps).
|
||||
# In CLI mode, the scriptblock runs directly in the current session.
|
||||
function Invoke-NonBlocking {
|
||||
param(
|
||||
[scriptblock]$ScriptBlock,
|
||||
[object[]]$ArgumentList = @(),
|
||||
[int]$TimeoutSeconds = 0
|
||||
)
|
||||
|
||||
# CLI mode without timeout: run directly in-process
|
||||
if (-not $script:GuiWindow -and $TimeoutSeconds -eq 0) {
|
||||
return (& $ScriptBlock @ArgumentList)
|
||||
}
|
||||
|
||||
$ps = [powershell]::Create()
|
||||
try {
|
||||
$null = $ps.AddScript($ScriptBlock.ToString())
|
||||
foreach ($arg in $ArgumentList) {
|
||||
$null = $ps.AddArgument($arg)
|
||||
}
|
||||
|
||||
$handle = $ps.BeginInvoke()
|
||||
|
||||
if ($script:GuiWindow) {
|
||||
# GUI mode: pump UI messages while waiting
|
||||
$stopwatch = if ($TimeoutSeconds -gt 0) { [System.Diagnostics.Stopwatch]::StartNew() } else { $null }
|
||||
|
||||
while (-not $handle.IsCompleted) {
|
||||
if ($stopwatch -and $stopwatch.Elapsed.TotalSeconds -ge $TimeoutSeconds) {
|
||||
$ps.Stop()
|
||||
throw "Operation timed out after $TimeoutSeconds seconds"
|
||||
}
|
||||
DoEvents
|
||||
Start-Sleep -Milliseconds 16
|
||||
}
|
||||
}
|
||||
else {
|
||||
# CLI mode with timeout: block until completion or timeout
|
||||
if (-not $handle.AsyncWaitHandle.WaitOne($TimeoutSeconds * 1000)) {
|
||||
$ps.Stop()
|
||||
throw "Operation timed out after $TimeoutSeconds seconds"
|
||||
}
|
||||
}
|
||||
|
||||
$result = $ps.EndInvoke($handle)
|
||||
|
||||
if ($result.Count -eq 0) { return $null }
|
||||
if ($result.Count -eq 1) { return $result[0] }
|
||||
return @($result)
|
||||
}
|
||||
finally {
|
||||
$ps.Dispose()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user