如何 运行 两个 Start-Job 并等待他们的结果?
How to run two Start-Job and wait for their results?
我有一个命令列表,我正在尝试分别使用 Start-Job 来调用它们。每个命令都应该 return 一个对象数组。我如何等待每个命令的数组并在所有命令完成后组合它们 运行?我正在使用 PS 5.1
cmds = "Command-One", "Command-Two"
foreach cmd in cmds
{
Start-Job -ScriptBlock { cmd }
}
一个简单的例子:
# Launch two jobs that each output two numbers,
# collect all their output, and clean up once they terminate.
" 1, 2 ", " 3, 4 " |
ForEach-Object { Start-Job -ScriptBlock ([scriptblock]::Create($_)) } |
Receive-Job -Wait -AutoRemoveJob
请注意输入命令 strings(设计为每个输出两个数字)必须如何转换为 script blocks via [scriptblock]::Create()
so that they can be passed to Start-Job
的 -ScriptBlock
参数。
但是,最好也更简单地以脚本块的形式提供命令;使用 script-block 文字 ({ ... }
):
{ 1, 2 }, { 3, 4 } |
ForEach-Object { Start-Job $_ } |
Receive-Job -Wait -AutoRemoveJob
如果您想将创建作业的时间与等待它们完成/收集它们的输出分开:
$jobs = { 1, 2 }, { 3, 4 } | ForEach-Object { Start-Job $_ }
# ... perform other tasks
$jobs | Receive-Job -Wait -AutoRemoveJob
所有变体启动两个作业并(直接或间接)通过管道传输 Start-Job
to Receive-Job
输出的作业对象,后者收集它们的输出(详情请参阅底部部分):
-Wait
额外等待两个作业完成,从而确保已接收到所有作业输出并输出
- 如果没有
-Wait
,Receive-Job
收集到目前为止 产生的所有输出 ,并立即收集 returns,因此可能需要多次调用;可选地,您可以收集输出而不使用它 (-Keep
)。
-AutoRemoveJob
之后自动清理作业,根据定义,这些作业届时已终止。
注意还有:
Wait-Job
仅执行等待,可选地针对给定的 state (-State
),并且可选地使用 timeout (-Timeout
),需要单独的 Receive-Job
调用来收集输出。
Remove-Job
仅删除作业,如果作业尚未完成,可选择包括强制终止 (-Force
)。
Receive-Job
如何收集输出:
作业永远不会直接输出到调用者的控制台 - 所有输出,甚至是 output streams other than the success stream, such as with Write-Host
- 都由 Receive-Job
收集并路由到调用者的相应输出流。
作业向 success 输出流(即 data 输出)发出的对象是 装饰有标识工作来源的属性:
包含 auto-generated 标识作业的 GUID 的属性。
.RunspaceId
.PSSourceJobInstanceId
(仅当作业为 运行 时,看起来很简单)
- 两者都会在每次调用时发生变化;请注意,您可以通过
-Name
传递给 Start-Job
的可选 self-chosen 符号名称在此处反映为 而不是 ,因此没有明显的关联方式输出对象及其来自的工作 - 见下文。
PowerShell 的 远程处理(其基础设施后台作业部分使用)主要感兴趣的另外两个属性:
.PSComputerName
:总是 'localhost'
在后台作业中
.PSShowComputerName
:总是在后台作业中 $false
;提示格式化系统是否显示 .PSComputerName
属性. 的值
为了说明以上几点:
# This collects 42 in $dataOutput, and prints
# 'Some status message' to the display; you could suppress that with 6>$null
$dataOutput =
Start-Job { Write-Host 'Some status message'; 42 } |
Receive-Job -Wait -AutoRemoveJob
# Use ConvertTo-Json to surface the additional properties the output
# object is decorated with; you'll see something like:
# {
# "value": 42,
# "PSComputerName": "localhost",
# "RunspaceId": "ba1c0710-cb55-4759-81a2-2b089edd92a7",
# "PSShowComputerName": false,
# "PSSourceJobInstanceId": "44422412-6bc2-4b0d-8379-ddd09b2d8e56"
# }
$dataOutput | ConvertTo-Json
如果您想分别为每个作业收集和发出输出:
$jobs = { 1, 2 }, { 3, 4 } | ForEach-Object { Start-Job $_ }
# Wait for all jobs to complete.
$jobs | Wait-Job
# Collect the output for each job separately.
# You'll see the following:
# VERBOSE: Output from job { 1, 2 }
# 1
# 2
# VERBOSE: Output from job { 3, 4 }
# 3
# 4
$jobs | ForEach-Object {
Write-Verbose -Verbose "Output from job { $($_.Command) }"
$_ | Receive-Job -Wait -AutoRemoveJob
}
我有一个命令列表,我正在尝试分别使用 Start-Job 来调用它们。每个命令都应该 return 一个对象数组。我如何等待每个命令的数组并在所有命令完成后组合它们 运行?我正在使用 PS 5.1
cmds = "Command-One", "Command-Two"
foreach cmd in cmds
{
Start-Job -ScriptBlock { cmd }
}
一个简单的例子:
# Launch two jobs that each output two numbers,
# collect all their output, and clean up once they terminate.
" 1, 2 ", " 3, 4 " |
ForEach-Object { Start-Job -ScriptBlock ([scriptblock]::Create($_)) } |
Receive-Job -Wait -AutoRemoveJob
请注意输入命令 strings(设计为每个输出两个数字)必须如何转换为 script blocks via [scriptblock]::Create()
so that they can be passed to Start-Job
的 -ScriptBlock
参数。
但是,最好也更简单地以脚本块的形式提供命令;使用 script-block 文字 ({ ... }
):
{ 1, 2 }, { 3, 4 } |
ForEach-Object { Start-Job $_ } |
Receive-Job -Wait -AutoRemoveJob
如果您想将创建作业的时间与等待它们完成/收集它们的输出分开:
$jobs = { 1, 2 }, { 3, 4 } | ForEach-Object { Start-Job $_ }
# ... perform other tasks
$jobs | Receive-Job -Wait -AutoRemoveJob
所有变体启动两个作业并(直接或间接)通过管道传输 Start-Job
to Receive-Job
输出的作业对象,后者收集它们的输出(详情请参阅底部部分):
-Wait
额外等待两个作业完成,从而确保已接收到所有作业输出并输出- 如果没有
-Wait
,Receive-Job
收集到目前为止 产生的所有输出 ,并立即收集 returns,因此可能需要多次调用;可选地,您可以收集输出而不使用它 (-Keep
)。
- 如果没有
-AutoRemoveJob
之后自动清理作业,根据定义,这些作业届时已终止。
注意还有:
Wait-Job
仅执行等待,可选地针对给定的 state (-State
),并且可选地使用 timeout (-Timeout
),需要单独的Receive-Job
调用来收集输出。Remove-Job
仅删除作业,如果作业尚未完成,可选择包括强制终止 (-Force
)。
Receive-Job
如何收集输出:
作业永远不会直接输出到调用者的控制台 - 所有输出,甚至是 output streams other than the success stream, such as with
Write-Host
- 都由Receive-Job
收集并路由到调用者的相应输出流。作业向 success 输出流(即 data 输出)发出的对象是 装饰有标识工作来源的属性:
包含 auto-generated 标识作业的 GUID 的属性。
.RunspaceId
.PSSourceJobInstanceId
(仅当作业为 运行 时,看起来很简单)- 两者都会在每次调用时发生变化;请注意,您可以通过
-Name
传递给Start-Job
的可选 self-chosen 符号名称在此处反映为 而不是 ,因此没有明显的关联方式输出对象及其来自的工作 - 见下文。
PowerShell 的 远程处理(其基础设施后台作业部分使用)主要感兴趣的另外两个属性:
.PSComputerName
:总是'localhost'
在后台作业中.PSShowComputerName
:总是在后台作业中$false
;提示格式化系统是否显示.PSComputerName
属性. 的值
为了说明以上几点:
# This collects 42 in $dataOutput, and prints
# 'Some status message' to the display; you could suppress that with 6>$null
$dataOutput =
Start-Job { Write-Host 'Some status message'; 42 } |
Receive-Job -Wait -AutoRemoveJob
# Use ConvertTo-Json to surface the additional properties the output
# object is decorated with; you'll see something like:
# {
# "value": 42,
# "PSComputerName": "localhost",
# "RunspaceId": "ba1c0710-cb55-4759-81a2-2b089edd92a7",
# "PSShowComputerName": false,
# "PSSourceJobInstanceId": "44422412-6bc2-4b0d-8379-ddd09b2d8e56"
# }
$dataOutput | ConvertTo-Json
如果您想分别为每个作业收集和发出输出:
$jobs = { 1, 2 }, { 3, 4 } | ForEach-Object { Start-Job $_ }
# Wait for all jobs to complete.
$jobs | Wait-Job
# Collect the output for each job separately.
# You'll see the following:
# VERBOSE: Output from job { 1, 2 }
# 1
# 2
# VERBOSE: Output from job { 3, 4 }
# 3
# 4
$jobs | ForEach-Object {
Write-Verbose -Verbose "Output from job { $($_.Command) }"
$_ | Receive-Job -Wait -AutoRemoveJob
}