Skip to content

Instantly share code, notes, and snippets.

@klinkby
Created June 24, 2019 12:38
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save klinkby/dafe333ecd6715a7f45bc656da39396c to your computer and use it in GitHub Desktop.
Save klinkby/dafe333ecd6715a7f45bc656da39396c to your computer and use it in GitHub Desktop.
Function CallbackWrapper {
param (
[string]$callbackScript,
[object]$param,
[int]$order
)
$callback = [ScriptBlock]::Create($callbackScript)
return [PSCustomObject]@{
Result = $callback.InvokeReturnAsIs($param)
Order = $order
}
}
Function Invoke-Parallel {
param(
[Parameter(Mandatory = $true)][Collections.IEnumerable]$WorkQueue,
[Parameter(Mandatory = $true)][ScriptBlock]$ScriptBlock,
[uint16]$MaxThreads = [uint16]$env:NUMBER_OF_PROCESSORS + 1
)
$t0 = [DateTime]::UtcNow
Write-Verbose "Initialize pool of $MaxThreads"
$pool = [RunspaceFactory]::CreateRunspacePool(1, $MaxThreads)
$pool.ApartmentState = "STA"
$pool.Open()
Write-Verbose "Queue up work"
try {
$i = 0
$state = $WorkQueue | ForEach-Object {
$runspace = [PowerShell]::Create()
$runspace.RunspacePool = $pool
$runspace.AddScript(${function:CallbackWrapper}) | Out-Null
$runspace.AddParameters(@("${ScriptBlock}", $_, $i++)) | Out-Null
$asyncResult = $runspace.BeginInvoke() # here we go
return [PSCustomObject]@{
Runspace = $runspace
AsyncResult = $asyncResult
}
}
Write-Verbose "Wait for $($state.Length) results"
$results = $state | ForEach-Object {
$result = $_.RunSpace.EndInvoke($_.AsyncResult) # inherently awaits completion
$_.RunSpace.Dispose()
return $result
}
}
finally {
Write-Verbose "Clean up"
$pool.Close()
$pool.Dispose()
}
Write-Verbose "Sort and unwrap"
$results `
| Sort-Object -Property Order `
| ForEach-Object { $_.Result }
Write-Verbose "Done in $(([DateTime]::UtcNow - $t0).TotalSeconds)s"
}
# Invoke-Parallel @(1,1,1,1,2,2,4,6,8) { param ($x) Start-Sleep $x }
Export-ModuleMember Invoke-Parallel
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment