Ответ Стива Таунсенда верен в теории, но не на практике, как указал @likwid. Мой исправленный код учитывает барьер контекста работы - по умолчанию ничто не преодолевает этот барьер! Таким образом, автоматическая $_
переменная может использоваться в цикле, но не может использоваться непосредственно в блоке сценария, потому что она находится внутри отдельного контекста, созданного заданием.
Чтобы передать переменные из родительского контекста в дочерний контекст, используйте -ArgumentList
параметр on Start-Job
для его отправки и используйте param
внутри блока скрипта для его получения.
cls
# Send in two root directory names, one that exists and one that does not.
# Should then get a "True" and a "False" result out the end.
"temp", "foo" | %{
$ScriptBlock = {
# accept the loop variable across the job-context barrier
param($name)
# Show the loop variable has made it through!
Write-Host "[processing '$name' inside the job]"
# Execute a command
Test-Path "\$name"
# Just wait for a bit...
Start-Sleep 5
}
# Show the loop variable here is correct
Write-Host "processing $_..."
# pass the loop variable across the job-context barrier
Start-Job $ScriptBlock -ArgumentList $_
}
# Wait for all to complete
While (Get-Job -State "Running") { Start-Sleep 2 }
# Display output from all jobs
Get-Job | Receive-Job
# Cleanup
Remove-Job *
(Обычно мне нравится давать ссылку на документацию PowerShell в качестве подтверждающего доказательства, но, увы, мой поиск оказался бесплодным. Если вы случайно знаете, где задокументировано разделение контекста, оставьте здесь комментарий, чтобы сообщить мне!)
receive-job (wait-job ($a = start-job { "heyo!" })); remove-job $a
или$a = start-job { "heyo!" }; wait-job $a; receive-job $a; remove-job $a
Также обратите внимание, что если вы позвонитеreceive-job
до завершения задания, вы можете вообще ничего не получить.