ZetCode

PowerShell Wait-Job

最后修改:2025 年 2 月 15 日

在本文中,我们将介绍 PowerShell 中的 Wait-Job cmdlet。此 cmdlet 会暂停执行,直到后台作业完成。它对于作业管理和同步至关重要。

作业基础

PowerShell 作业代表一个独立运行的后台任务。作业允许命令并行执行,而不会阻塞控制台。每个作业都有一个状态(运行中、已完成、失败)和输出数据。Wait-Job cmdlet 会暂停执行,直到指定的作业完成。

Wait-Job 的基本用法

使用 Wait-Job 的最简单方法是配合作业对象。这会暂停脚本,直到作业完成。完成后,cmdlet 会返回作业对象。基本用法不需要任何参数。

waitjob1.ps1
$job = Start-Job -ScriptBlock { Start-Sleep -Seconds 5 }
Wait-Job $job

此脚本启动一个休眠 5 秒的后台作业。Wait-Job 会暂停执行,直到作业完成。在等待期间,控制台仍然响应。

等待多个作业

Wait-Job 可以接受多个作业对象作为输入。它会一直等待,直到所有指定的作业都完成。作业可以通过数组或管道传递。这对于并行任务很有用。

waitjob2.ps1
$job1 = Start-Job -ScriptBlock { Start-Sleep -Seconds 3 }
$job2 = Start-Job -ScriptBlock { Start-Sleep -Seconds 5 }
Wait-Job $job1, $job2

此示例启动两个具有不同休眠时长的作业。Wait-Job 会等待两者都完成后再继续。总等待时间取决于运行时间最长的作业。

-Timeout 参数

-Timeout 参数限制等待作业的时间。如果在超时时间内作业未完成,执行将继续。该值以秒为单位指定。这可以防止无限期阻塞。

waitjob3.ps1
$job = Start-Job -ScriptBlock { Start-Sleep -Seconds 10 }
Wait-Job $job -Timeout 5

此脚本启动一个 10 秒的作业,但只等待 5 秒。超时后,作业将继续在后台运行。cmdlet 会在 5 秒后将控制权返回给脚本。

等待任何作业完成

-Any 参数使 Wait-Job 在任何指定作业完成后立即返回。这对于需要第一个可用结果的场景很有用。其他作业将继续运行。

waitjob4.ps1
$job1 = Start-Job -ScriptBlock { Start-Sleep -Seconds 3 }
$job2 = Start-Job -ScriptBlock { Start-Sleep -Seconds 5 }
Wait-Job $job1, $job2 -Any

此示例等待其中一个作业完成。cmdlet 在 3 秒后,当第一个作业完成时返回。第二个作业继续在后台运行。

管道输入

Wait-Job 通过管道接受作业对象。这允许与其他作业相关的 cmdlet 链式调用。在处理多个作业时,管道输入的语法更简洁。管道输入与参数输入以相同方式处理。

waitjob5.ps1
Get-Job | Wait-Job

此命令等待所有当前作业完成。Get-Job 检索所有作业对象,并将它们通过管道传递给 Wait-Job。这对于批量处理很方便。

等待后检索作业结果

等待作业完成后,通常需要检索结果。使用 Receive-Job 来获取已完成作业的输出。这应该在 Wait-Job 确认完成之后进行。

waitjob6.ps1
$job = Start-Job -ScriptBlock { Get-Process }
Wait-Job $job
Receive-Job $job

此脚本启动一个获取进程的作业,等待其完成,然后检索结果。输出与直接运行 Get-Process 相同,但它是后台执行的。

错误处理

等待后可以检测到失败的作业。检查作业的 State 属性是否为“Failed”。Error 属性包含失败的详细信息。这允许在脚本中进行适当的错误处理。

waitjob7.ps1
$job = Start-Job -ScriptBlock { Get-Item "nonexistent.txt" }
Wait-Job $job
if ($job.State -eq "Failed") {
    $job.Error
}

此示例尝试在作业中访问不存在的文件。等待后,它会检查是否失败并显示错误。错误消息解释了作业失败的原因。

等待远程作业

Wait-Job 可用于在远程计算机上运行的作业。必须使用 -AsJob 参数配合 Invoke-Command 来启动作业。等待行为与本地作业相同。

waitjob8.ps1
$job = Invoke-Command -ComputerName Server01 -ScriptBlock { 
    Get-Process 
} -AsJob
Wait-Job $job
Receive-Job $job

此脚本在远程计算机上运行 Get-ProcessWait-Job 会暂停,直到远程作业完成。然后检索结果并在本地显示。

来源

PowerShell 文档

在本文中,我们介绍了 PowerShell 中的 Wait-Job cmdlet。

作者

我的名字是 Jan Bodnar,我是一名充满热情的程序员,拥有丰富的编程经验。我从 2007 年开始撰写编程文章。迄今为止,我已撰写了 1400 多篇文章和 8 本电子书。我在编程教学方面拥有十多年的经验。

列出 所有 PowerShell 教程