# encoding: ascii
# api: powershell
# title: Boots & Background Jobs
# description: This sample was put together with Jaykul’s help and bits and pieces were taken from the Sample.ps1 distributed with PowerBoots
# version: 0.7
# type: module
# author: foureight84
# license: CC0
# function: Start-FakeDownload
# x-poshcode-id: 2307
# x-derived-from-id: 2315
# x-archived: 2010-12-15T12:09:22
#
# Shows how you can invoke a long running function from an event handler using background jobs in order to maintain UI responsiveness.
# IMPORTANT ****
# # Make sure that Powershell is running on .NET 2.0 CLR instead of .NET 4.0. Background jobs and remoting does not function properly under 4.0.
#
Import-Module PowerBoots
# This simulates a download function, say Jaykul's Get-Webfile
# You can output current progress for a large file, or if it's an array of links then out put the current (index/length)%
# You will need to run the function as a background thread in order for it to not interfere with the UI thread (freezes UI) when called from event handler.
Function Start-FakeDownload {
$global:job = Start-Job {
foreach ($i in $(1..50)){
sleep 0.7
($i/50)*100
}
}
}
# GUI using boots. Registers controls as global variables.
$global:Window = Boots -Width 250 -Async -Passthru -Title "Progress Meter" {
StackPanel {
ProgressBar -Height 25 -Name "Progress" | tee -var global:progress
Button "Download" -Name "Download" | tee -var global:download
Textblock | Tee -var global:status
}
}
# Add event handler for the Download button.
# Runs Background job and updates Ui
$download.Add_Click({
# Prevents download from being pressed while running ... causes overload with $timer.
$download.IsEnabled = $false
$download.Content = "Downloading..."
# Get background job out and updates controls with value
$updateblock = {
# Notice the -Keep usage. Job result/output clears everytime you Receive-Job.
# -Keep allows us to get the result from the background job multiple times and also serves as a marker to figure out when the job completes
if($($job.State -eq "Running") -or $($($job.State -eq "Completed") -and $($(Receive-Job $job -Keep)[-1] -eq 100))){
Invoke-BootsWindow $Window {
$progress.Value = $(Receive-Job $job -Keep)[-1]
$status.Text = "$($(Receive-Job $job)[-1])`% done"
}
}
if($($job.State -eq "Completed") -and $($(Receive-Job $job) -eq $null)){
Invoke-BootsWindow $Window {
$status.Text = "Download Complete"
}
$timer.Stop()
$download.Content = "Download"
$download.IsEnabled = $true
}
}
$timer = new-object System.Windows.Threading.DispatcherTimer
$timer.Interval = [TimeSpan]"0:0:3"
$timer.Add_Tick( $updateBlock )
Start-FakeDownload
$timer.start()
})