Skip to content

Instantly share code, notes, and snippets.

@michaellwest
Last active October 4, 2020 15:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save michaellwest/6f532d84da6986b3d4b866a651e2f7d6 to your computer and use it in GitHub Desktop.
Save michaellwest/6f532d84da6986b3d4b866a651e2f7d6 to your computer and use it in GitHub Desktop.
Create simple runspaces in PowerShell.
$watch = [System.Diagnostics.Stopwatch]::StartNew()
# BLOCK 1: Create and open runspace pool, setup runspaces array with min and max threads
$pool = [RunspaceFactory]::CreateRunspacePool(1, [int]$env:NUMBER_OF_PROCESSORS+1)
$pool.Open()
$runspaces = $results = @()
# BLOCK 2: Create reusable scriptblock. This is the workhorse of the runspace. Think of it as a function.
$scriptblock = {
param (
[string]$Data
)
Start-Sleep -Seconds 1
}
foreach($num in 1..20) {
# BLOCK 3: Create runspace and add to runspace pool
$runspace = [PowerShell]::Create()
$null = $runspace.AddScript($scriptblock)
$null = $runspace.AddArgument($num)
$runspace.RunspacePool = $pool
# BLOCK 4: Add runspace to runspaces collection and "start" it
# Asynchronously runs the commands of the PowerShell object pipeline
$runspaces += [PSCustomObject]@{ Pipe = $runspace; Status = $runspace.BeginInvoke() }
}
# BLOCK 5: Wait for runspaces to finish
while ($runspaces.Status.IsCompleted -notcontains $true) {}
# BLOCK 6: Clean up
foreach ($runspace in $runspaces) {
# EndInvoke method retrieves the results of the asynchronous call
$results += $runspace.Pipe.EndInvoke($runspace.Status)
$runspace.Pipe.Dispose()
}
$pool.Close()
$pool.Dispose()
# Bonus block 7
# Look at $results to see any errors or whatever was returned from the runspaces
$watch.Stop()
$watch.ElapsedMilliseconds / 1000
$watch = [System.Diagnostics.Stopwatch]::StartNew()
$items = Get-ChildItem -Path "master:" -ID "{F8FD1710-E835-402D-B0DB-0537887DBE00}"
foreach($item in $items) {
$yaml = $item | ConvertTo-RainbowYaml
$rainbowItem = ConvertFrom-RainbowYaml -Yaml $yaml
Import-RainbowItem -Item $rainbowItem
}
$watch.Stop()
$watch.ElapsedMilliseconds / 1000
$watch = [System.Diagnostics.Stopwatch]::StartNew()
$script = {
$yaml = $item | ConvertTo-RainbowYaml
$rainbowItem = ConvertFrom-RainbowYaml -Yaml $yaml
Import-RainbowItem -Item $rainbowItem
$true
}
$maxParallel = 20
$sessions = [System.Collections.ArrayList]@()
$requestItemQueue = [System.Collections.Generic.Queue[Item]]@()
$items = Get-ChildItem -Path "master:" -ID "{110D559F-DEA5-42EA-9C1C-8A5DF7E70EF9}" -Recurse
foreach($item in $items) {
$requestItemQueue.Enqueue($item)
}
$finishedSessions = [System.Collections.ArrayList]@()
while($requestItemQueue.Count -gt 0) {
if($sessions.Count -ge $maxParallel) {
$finished = @($sessions | Wait-ScriptSession -Any)
$finishedSessions.AddRange($finished) > $null
foreach($fin in $finished) {
$sessions.Remove($fin) > $null
}
}
$requestItem = $requestItemQueue.Dequeue()
$s = Start-ScriptSession -ScriptBlock $script -ArgumentList @{"item"=$requestItem}
$sessions.Add($s) > $null
}
if($sessions.Count -gt 0) {
$finished = @($sessions | Wait-ScriptSession)
$finishedSessions.AddRange($finished) > $null
}
$finishedSessions | Receive-ScriptSession
$watch.Stop()
$watch.ElapsedMilliseconds / 1000
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment