Start-ThreadJob
创建类似于 cmdlet 的 Start-Job
后台作业。
语法
Start-ThreadJob
[-ScriptBlock] <ScriptBlock>
[-Name <String>]
[-InitializationScript <ScriptBlock>]
[-InputObject <PSObject>]
[-ArgumentList <Object[]>]
[-ThrottleLimit <Int32>]
[-StreamingHost <PSHost>]
[<CommonParameters>]
Start-ThreadJob
[-FilePath] <String>
[-Name <String>]
[-InitializationScript <ScriptBlock>]
[-InputObject <PSObject>]
[-ArgumentList <Object[]>]
[-ThrottleLimit <Int32>]
[-StreamingHost <PSHost>]
[<CommonParameters>]
说明
Start-ThreadJob
创建类似于 cmdlet 的 Start-Job
后台作业。 main区别在于,创建的作业在本地进程中的单独线程中运行。 默认情况下,作业使用启动作业的调用方当前工作目录。
cmdlet 还支持 ThrottleLimit 参数来限制一次运行的作业数。 随着更多的作业启动,它们将排队等待,直到当前作业数低于限制。
示例
示例 1 - Create线程限制为 2 的后台作业
Start-ThreadJob -ScriptBlock { 1..100 | % { sleep 1; "Output $_" } } -ThrottleLimit 2
Start-ThreadJob -ScriptBlock { 1..100 | % { sleep 1; "Output $_" } }
Start-ThreadJob -ScriptBlock { 1..100 | % { sleep 1; "Output $_" } }
Get-Job
Id Name PSJobTypeName State HasMoreData Location Command
-- ---- ------------- ----- ----------- -------- -------
1 Job1 ThreadJob Running True PowerShell 1..100 | % { sleep 1;...
2 Job2 ThreadJob Running True PowerShell 1..100 | % { sleep 1;...
3 Job3 ThreadJob NotStarted False PowerShell 1..100 | % { sleep 1;...
示例 2 - 比较 Start-Job 和 Start-ThreadJob 的性能
此示例显示 和 Start-ThreadJob
之间的差异Start-Job
。 作业运行 Start-Sleep
cmdlet 1 秒。 由于作业并行运行,因此总执行时间约为 1 秒,加上创建作业所需的任何时间。
# start five background jobs each running 1 second
Measure-Command {1..5 | % {Start-Job {Start-Sleep 1}} | Wait-Job} | Select-Object TotalSeconds
Measure-Command {1..5 | % {Start-ThreadJob {Start-Sleep 1}} | Wait-Job} | Select-Object TotalSeconds
TotalSeconds
------------
5.7665849
1.5735008
减去 1 秒的执行时间后,可以看到创建 Start-Job
5 个作业大约需要 4.8 秒。 Start-ThreadJob
速度快 8 倍,创建 5 个作业大约需要 0.6 秒。 结果可能因环境而异,但相对改进应相同。
示例 3 - 使用 InputObject Create作业
在此示例中,脚本块使用 $input
变量从 InputObject 参数接收输入。 这也可以通过将 对象管道连接到 Start-ThreadJob
来完成。
$j = Start-ThreadJob -InputObject (Get-Process pwsh) -ScriptBlock { $input | Out-String }
$j | Wait-Job | Receive-Job
NPM(K) PM(M) WS(M) CPU(s) Id SI ProcessName
------ ----- ----- ------ -- -- -----------
94 145.80 159.02 18.31 18276 1 pwsh
101 163.30 222.05 29.00 35928 1 pwsh
$j = Get-Process pwsh | Start-ThreadJob -ScriptBlock { $input | Out-String }
$j | Wait-Job | Receive-Job
NPM(K) PM(M) WS(M) CPU(s) Id SI ProcessName
------ ----- ----- ------ -- -- -----------
94 145.80 159.02 18.31 18276 1 pwsh
101 163.30 222.05 29.00 35928 1 pwsh
示例 4 - 将作业输出Stream父主机
使用 StreamingHost 参数,可以告知作业将所有主机输出定向到特定主机。 如果没有此参数,输出将进入作业数据流集合,并且不会显示在主机控制台中,直到收到作业的输出。
对于此示例,使用$Host
自动变量将Start-ThreadJob
当前主机传递给 。
PS> Start-ThreadJob -ScriptBlock { Read-Host 'Say hello'; Write-Warning 'Warning output' } -StreamingHost $Host
Id Name PSJobTypeName State HasMoreData Location Command
-- ---- ------------- ----- ----------- -------- -------
7 Job7 ThreadJob NotStarted False PowerShell Read-Host 'Say hello'; ...
PS> Say hello: Hello
WARNING: Warning output
PS> Receive-Job -Id 7
Hello
WARNING: Warning output
PS>
请注意,将显示 的提示, Read-Host
并且你可以键入输入。 然后,显示来自 Write-Warning
的消息。 cmdlet Receive-Job
返回作业的所有输出。
示例 5 - 同时下载多个文件
cmdlet Invoke-WebRequest
一次只能下载一个文件。 以下示例使用 Start-ThreadJob
创建多个线程作业来同时下载多个文件。
$baseUri = 'https://github.com/PowerShell/PowerShell/releases/download'
$files = @(
@{
Uri = "$baseUri/v7.3.0-preview.5/PowerShell-7.3.0-preview.5-win-x64.msi"
OutFile = 'PowerShell-7.3.0-preview.5-win-x64.msi'
},
@{
Uri = "$baseUri/v7.3.0-preview.5/PowerShell-7.3.0-preview.5-win-x64.zip"
OutFile = 'PowerShell-7.3.0-preview.5-win-x64.zip'
},
@{
Uri = "$baseUri/v7.2.5/PowerShell-7.2.5-win-x64.msi"
OutFile = 'PowerShell-7.2.5-win-x64.msi'
},
@{
Uri = "$baseUri/v7.2.5/PowerShell-7.2.5-win-x64.zip"
OutFile = 'PowerShell-7.2.5-win-x64.zip'
}
)
$jobs = @()
foreach ($file in $files) {
$jobs += Start-ThreadJob -Name $file.OutFile -ScriptBlock {
$params = $using:file
Invoke-WebRequest @params
}
}
Write-Host "Downloads started..."
Wait-Job -Job $jobs
foreach ($job in $jobs) {
Receive-Job -Job $job
}
参数
-ArgumentList
为 FilePath 或 ScriptBlock 参数指定的脚本指定参数或参数值的数组。
ArgumentList 必须是命令行上的最后一个参数。 参数名称后面的所有值都是参数列表中的解释值。
Type: | Object[] |
Position: | Named |
Default value: | None |
Required: | False |
Accept pipeline input: | False |
Accept wildcard characters: | False |
-FilePath
指定要作为后台作业运行的脚本文件。 输入脚本的路径和文件名。 脚本必须位于本地计算机或本地计算机可以访问的文件夹中。
使用此参数时,PowerShell 会将指定脚本文件的内容转换为脚本块,并将脚本块作为后台作业运行。
Type: | String |
Position: | 0 |
Default value: | None |
Required: | True |
Accept pipeline input: | False |
Accept wildcard characters: | False |
-InitializationScript
指定在作业开始前运行的命令。 将命令括在大括号 ({}
) 以创建脚本块。
使用此参数可以准备运行作业的会话。 例如,可以使用它向会话添加函数和模块。
Type: | ScriptBlock |
Position: | Named |
Default value: | None |
Required: | False |
Accept pipeline input: | False |
Accept wildcard characters: | False |
-InputObject
指定用作脚本块输入的对象。 它还允许管道输入。 $input
使用脚本块中的自动变量访问输入对象。
Type: | PSObject |
Position: | Named |
Default value: | None |
Required: | False |
Accept pipeline input: | True |
Accept wildcard characters: | False |
-Name
为新作业指定一个友好名称。 可以使用 名称向其他作业 cmdlet(如 cmdlet) Stop-Job
标识作业。
默认友好名称为“Job#”,其中“#”是每个作业递增的序号。
Type: | String |
Position: | Named |
Default value: | None |
Required: | False |
Accept pipeline input: | False |
Accept wildcard characters: | False |
-ScriptBlock
指定要在后台作业中运行的命令。 将命令括在大括号 ({}
) 以创建脚本块。 $Input
使用自动变量访问 InputObject 参数的值。 此参数是必需的。
Type: | ScriptBlock |
Position: | 0 |
Default value: | None |
Required: | True |
Accept pipeline input: | False |
Accept wildcard characters: | False |
-StreamingHost
此参数提供了一种线程安全方法,允许 Write-Host
输出直接转到 PSHost 对象中传递的 。 如果没有它, Write-Host
输出将进入作业信息数据流集合,在作业完成运行之前不会显示在主机控制台中。
Type: | PSHost |
Position: | Named |
Default value: | None |
Required: | False |
Accept pipeline input: | False |
Accept wildcard characters: | False |
-ThrottleLimit
此参数限制一次运行的作业数。 启动作业时,它们会排队,并等待线程池中的线程可用以运行作业。 默认限制为 5 个线程。
线程池大小对于 PowerShell 会话是全局的。 在一个调用中指定 ThrottleLimit 将设置同一会话中后续调用的限制。
Type: | Int32 |
Position: | Named |
Default value: | 5 |
Required: | False |
Accept pipeline input: | False |
Accept wildcard characters: | False |
输入
输出
ThreadJob.ThreadJob