Start-ThreadJob
Creates background jobs similar to the Start-Job
cmdlet.
Syntax
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>]
Description
Start-ThreadJob
creates background jobs similar to the Start-Job
cmdlet. The main difference is
that the jobs which are created run in separate threads within the local process. By default, the
jobs use the current working directory of the caller that started the job.
The cmdlet also supports a ThrottleLimit parameter to limit the number of jobs running at one time. As more jobs are started, they are queued and wait until the current number of jobs drops below the throttle limit.
Examples
Example 1 - Create background jobs with a thread limit of 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;...
Example 2 - Compare the performance of Start-Job and Start-ThreadJob
This example shows the difference between Start-Job
and Start-ThreadJob
. The jobs run the
Start-Sleep
cmdlet for 1 second. Since the jobs run in parallel, the total execution time
is about 1 second, plus any time required to create the jobs.
# 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
After subtracting 1 second for execution time, you can see that Start-Job
takes about 4.8 seconds
to create five jobs. Start-ThreadJob
is 8 times faster, taking about 0.6 seconds to create five
jobs. The results may vary in your environment but the relative improvement should be the same.
Example 3 - Create jobs using InputObject
In this example, the script block uses the $input
variable to receive input from the
InputObject parameter. This can also be done by piping objects to 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
Example 4 - Stream job output to parent host
Using the StreamingHost parameter you can tell a job to direct all host output to a specific host. Without this parameter the output goes to the job data stream collection and doesn't appear in a host console until you receive the output from the job.
For this example, the current host is passed to Start-ThreadJob
using the $Host
automatic
variable.
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>
Notice that the prompt from Read-Host
is displayed and you are able to type input. Then, the
message from Write-Warning
is displayed. The Receive-Job
cmdlet returns all the output from the
job.
Example 5 - Download multiple files at the same time
The Invoke-WebRequest
cmdlet can only download one file at a time. The following example uses
Start-ThreadJob
to create multiple thread jobs to download multiple files at the same time.
$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
}
Parameters
-ArgumentList
Specifies an array of arguments, or parameter values, for the script that is specified by the FilePath or ScriptBlock parameters.
ArgumentList must be the last parameter on the command line. All the values that follow the parameter name are interpreted values in the argument list.
Type: | Object[] |
Position: | Named |
Default value: | None |
Required: | False |
Accept pipeline input: | False |
Accept wildcard characters: | False |
-FilePath
Specifies a script file to run as a background job. Enter the path and filename of the script. The script must be on the local computer or in a folder that the local computer can access.
When you use this parameter, PowerShell converts the contents of the specified script file to a script block and runs the script block as a background job.
Type: | String |
Position: | 0 |
Default value: | None |
Required: | True |
Accept pipeline input: | False |
Accept wildcard characters: | False |
-InitializationScript
Specifies commands that run before the job starts. Enclose the commands in braces ({}
) to create
a script block.
Use this parameter to prepare the session in which the job runs. For example, you can use it to add functions and modules to the session.
Type: | ScriptBlock |
Position: | Named |
Default value: | None |
Required: | False |
Accept pipeline input: | False |
Accept wildcard characters: | False |
-InputObject
Specifies the objects used as input to the script block. It also allows for pipeline input. Use the
$input
automatic variable in the script block to access the input objects.
Type: | PSObject |
Position: | Named |
Default value: | None |
Required: | False |
Accept pipeline input: | True |
Accept wildcard characters: | False |
-Name
Specifies a friendly name for the new job. You can use the name to identify the job to other job
cmdlets, such as the Stop-Job
cmdlet.
The default friendly name is "Job#", where "#" is an ordinal number that is incremented for each job.
Type: | String |
Position: | Named |
Default value: | None |
Required: | False |
Accept pipeline input: | False |
Accept wildcard characters: | False |
-ScriptBlock
Specifies the commands to run in the background job. Enclose the commands in braces ({}
) to create
a script block. Use the $Input
automatic variable to access the value of the InputObject
parameter. This parameter is required.
Type: | ScriptBlock |
Position: | 0 |
Default value: | None |
Required: | True |
Accept pipeline input: | False |
Accept wildcard characters: | False |
-StreamingHost
This parameter provides a thread safe way to allow Write-Host
output to go directly to the passed
in PSHost object. Without it, Write-Host
output goes to the job information data stream
collection and doesn't appear in a host console until after the jobs finish running.
Type: | PSHost |
Position: | Named |
Default value: | None |
Required: | False |
Accept pipeline input: | False |
Accept wildcard characters: | False |
-ThrottleLimit
This parameter limits the number of jobs running at one time. As jobs are started, they are queued and wait until a thread is available in the thread pool to run the job. The default limit is 5 threads.
The thread pool size is global to the PowerShell session. Specifying a ThrottleLimit in one call sets the limit for subsequent calls in the same session.
Type: | Int32 |
Position: | Named |
Default value: | 5 |
Required: | False |
Accept pipeline input: | False |
Accept wildcard characters: | False |
Inputs
Outputs
ThreadJob.ThreadJob