Esta es el arreglo más acertada que encomtrarás brindar, pero obsérvala pausadamente y analiza si se adapta a tu trabajo.
Solución:
No es necesario actualizar para esto. Defina un bloque de script y use Start-Job
para ejecutar el bloque de script tantas veces como sea necesario. Ejemplo:
$cmd =
param($a, $b)
Write-Host $a $b
$foo = "foo"
1..5 | ForEach-Object
Start-Job -ScriptBlock $cmd -ArgumentList $_, $foo
El bloque de script toma 2 parámetros $a
y $b
que son pasados por el -ArgumentList
opción. En el ejemplo anterior, las asignaciones son $_
→ $a
y $foo
→ $b
. $foo
es solo un ejemplo para un configurable, pero static parámetro.
Correr Get-Job | Remove-Job
en algún momento para eliminar los trabajos terminados de la cola (o Get-Job | % Receive-Job $_.Id; Remove-Job $_.Id
si desea recuperar la salida).
Aquí hay un scriptblock falso rápido con el propósito de probar:
$Code =
param ($init)
$start = Get-Date
(1..30)
Este scriptblock se puede pasar a Start-Job
con por ejemplo 3 parámetros (10, 15, 35)
$jobs = @()
(10,15,35) | % $jobs += Start-Job -ArgumentList $_ -ScriptBlock $Code
Wait-Job -Job $jobs | Out-Null
Receive-Job -Job $jobs
Esto crea 3 trabajos, asígnalos a la $jobs
variable, los ejecuta en paralelo y luego espera a que terminen estos 3 trabajos y recupera los resultados:
Counted from 10 until 40 in 00:00:30.0147167.
Counted from 15 until 45 in 00:00:30.0057163.
Counted from 35 until 65 in 00:00:30.0067163.
Esto no tardó 90 segundos en ejecutarse, solo 30.
Una de las partes difíciles es proporcionar -Argumentlist
para Start-Job
e incluir un param()
bloque dentro de ScriptBlock. De lo contrario, el scriptblock nunca verá sus valores.
Puede usar una alternativa que puede ser más rápida que invocar trabajos si la función no es de ejecución prolongada. El subproceso máximo es 25 y solo invoco esta función 10 veces, por lo que espero que mi tiempo de ejecución total sea de 5 segundos. Puede envolver Medida-Comando alrededor de la declaración ‘resultados =’ para ver las estadísticas.
Ejemplo:
$ScriptBlock =
Param ( [int]$RunNumber )
Start-Sleep -Seconds 5
Return $RunNumber
$runNumbers = @(1..10)
$MaxThreads = 25
$runspacePool = [RunspaceFactory ]::CreateRunspacePool(1, $MaxThreads)
$runspacePool.Open()
$pipeLines = foreach($num in $runNumbers)
$pipeline = [powershell]::Create()
$pipeline.RunspacePool = $runspacePool
$pipeline.AddScript($ScriptBlock)
#obtain results as they come.
$results = foreach($pipeline in $pipeLines)
$pipeline.EndInvoke($pipeline.AsyncResult )
#cleanup code.
$pipeLines | % $_.Dispose()
$pipeLines = $null
if ( $runspacePool ) $runspacePool.Close()
#your results
$results
No se te olvide mostrar esta sección si te valió la pena.