$job = Start-Job -ScriptBlock { sleep 5; Write-Host "Hello world."; }
Wait-Job $job
Receive-Job -Job $job
把上面的代码保存到文件 mytask.ps1 中执行:

Receive-Job 命令输出了我们在后台执行的任务的 output。
在后台执行多个任务并等待结束
因为 Start-Job 命令是非阻塞的,所以理论上我们可以执行任意多次从而启动很多的后台任务。和等待单个任务相同,仍然可以使用 Wait-Job 命令来等待所有的任务结束,不过此时需要配合 Get-Job 命令一起使用:
> Get-Job | Wait-Job
更常用的方式是我们在 while 循环中不断的检查任务的状态,当所有任务的状态都是 "Completed" 时表示全部任务执行结束:
Remove-Job *
#测试计时开始
$start_time = (Get-Date)
Start-Job -ScriptBlock { sleep 9; Write-Host "Hello myJob1."; } -Name "myJob1"
Start-Job -ScriptBlock { sleep 5; Write-Host "Hello myJob2."; } -Name "myJob2"
$taskCount = 2
while($taskCount -gt 0)
{
foreach($job in Get-Job)
{
$state = [string]$job.State
if($state -eq "Completed")
{
Write-Host($job.Name + " 已经完成")
Receive-Job $job
$taskCount--
Remove-Job $job
}
}
sleep 1
}
"所有任务已完成"
#得出任务运行的时间
(New-TimeSpan $start_time).totalseconds
把上面的代码保存到 mytask.ps1 文件中并执行:

代码中我们给每个任务起了名字,并在 while 循环中不断的使用 Get-Job 命令检查任务当前的状态,如果发现任务的状态为 "Completed",就通过 Remove-Job 命令删除它,并在删除前打印任务的名称和 output。
封装一个执行后台任务的函数
下面我们用封装一个简单的函数来并行执行多个任务:
function Run-Tasks
{
Param
(
$taskArr,
$parallelcount=1
)
#测试计时开始
$startTime = (Get-Date)
#移除本次会话中已有的所有后台任务
Remove-Job *
# 使用变量 $taskCount 保存还没有执行完成的任务数
$taskCount = $taskArr.Length
#判断设定的并行任务数是否超过当前任务队列中的任务数
if($parallelCount -gt $taskArr.Length)
{
$parallelCount = $taskArr.Length
}
#启动初始任务
foreach($i in 1..$parallelCount)
{
Start-Job $taskArr[$i - 1] -Name "task$i"
}
#初始任务完成后开始的任务
$nextIndex = $parallelCount
#当任务队列中还有任务时不断轮询已建立的任务,当一个后台任务结束时删除这个任务,
#然后从任务队列中取出下一个任务进行执行,然后等待所有任务执行完成。
while(($nextIndex -lt $taskArr.Length) -or ($taskCount -gt 0))
{
foreach($job in Get-Job)
{
$state = [string]$job.State
if($state -eq "Completed")
{
Write-Host($job.Name + " 已经完成,结果如下:")
Receive-Job $job
Remove-Job $job
$taskCount--
if($nextIndex -lt $taskArr.Length)
{
$taskNumber = $nextIndex + 1
Start-Job $taskArr[$nextIndex] -Name "task$taskNumber"
$nextIndex++
}
}
}
sleep 1
}
"所有任务已完成"
#得出任务运行的时间
(New-TimeSpan $startTime).totalseconds
}










