Поделиться через


Start-ThreadJob

Создает фоновые задания, аналогичные командлету 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 создает фоновые задания, аналогичные командлету Start-Job. Основное различие заключается в том, что задания, созданные в отдельных потоках в локальном процессе. По умолчанию задания используют текущий рабочий каталог вызывающего объекта, запускающего задание.

Командлет также поддерживает параметр ThrottleLimit, чтобы ограничить количество заданий, выполняемых одновременно. По мере запуска заданий они помещаются в очередь и ожидают, пока текущее число заданий не упадет ниже ограничения регулирования.

Примеры

Пример 1. Создание фоновых заданий с ограничением потока 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-Job и Start-ThreadJob. Задания запускают командлет Start-Sleep в течение 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 занимает около 4,8 секунд, чтобы создать пять заданий. Start-ThreadJob 8 раз быстрее, что занимает около 0,6 секунд, чтобы создать пять заданий. Результаты могут отличаться в вашей среде, но относительное улучшение должно совпадать.

Пример 3. Создание заданий с помощью InputObject

В этом примере блок скрипта использует переменную $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. Потоковая передача выходных данных задания родительскому узлу

С помощью параметра StreamingHost можно указать задание, чтобы направлять все выходные данные узла на определенный узел. Без этого параметра выходные данные передаются в коллекцию потоков данных задания и не отображаются в консоли узла, пока не получите выходные данные задания.

В этом примере текущий узел передается в Start-ThreadJob с помощью $Host автоматической переменной.

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. Командлет Receive-Job возвращает все выходные данные задания.

Пример 5. Скачивание нескольких файлов одновременно

Командлет 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 должен быть последним параметром в командной строке. Все значения, следуют имени параметра, интерпретируются в списке аргументов.

Тип:Object[]
Position:Named
Default value:None
Обязательно:False
Принять входные данные конвейера:False
Принять подстановочные знаки:False

-FilePath

Указывает файл скрипта для запуска в качестве фонового задания. Введите путь и имя файла скрипта. Скрипт должен находиться на локальном компьютере или в папке, к которым может получить доступ локальный компьютер.

При использовании этого параметра PowerShell преобразует содержимое указанного файла скрипта в блок скрипта и запускает блок скрипта в качестве фонового задания.

Тип:String
Position:0
Default value:None
Обязательно:True
Принять входные данные конвейера:False
Принять подстановочные знаки:False

-InitializationScript

Задает команды, которые выполняются перед началом задания. Заключите команды в фигурные скобки ({}) для создания блока скрипта.

Используйте этот параметр для подготовки сеанса, в котором выполняется задание. Например, его можно использовать для добавления функций и модулей в сеанс.

Тип:ScriptBlock
Position:Named
Default value:None
Обязательно:False
Принять входные данные конвейера:False
Принять подстановочные знаки:False

-InputObject

Указывает объекты, используемые в качестве входных данных в блок скрипта. Он также позволяет вводить входные данные конвейера. Используйте $input автоматическую переменную в блоке скрипта для доступа к входным объектам.

Тип:PSObject
Position:Named
Default value:None
Обязательно:False
Принять входные данные конвейера:True
Принять подстановочные знаки:False

-Name

Задает понятное имя для нового задания. Имя можно использовать для идентификации задания для других командлетов заданий, таких как командлет Stop-Job.

Понятное по умолчанию имя — Job#, где "#" — порядковое число, которое увеличивается для каждого задания.

Тип:String
Position:Named
Default value:None
Обязательно:False
Принять входные данные конвейера:False
Принять подстановочные знаки:False

-ScriptBlock

Указывает команды, выполняемые в фоновом задании. Заключите команды в фигурные скобки ({}) для создания блока скрипта. Используйте $Input автоматическую переменную для доступа к значению параметра InputObject. Этот параметр является обязательным.

Тип:ScriptBlock
Position:0
Default value:None
Обязательно:True
Принять входные данные конвейера:False
Принять подстановочные знаки:False

-StreamingHost

Этот параметр предоставляет потокобезопасный способ, позволяющий выходным данным перейти непосредственно к переданному объекту PSHost . Без него Write-Host выходные данные передаются в коллекцию потоков данных о задании и не отображаются в консоли узла до завершения выполнения заданий.

Тип:PSHost
Position:Named
Default value:None
Обязательно:False
Принять входные данные конвейера:False
Принять подстановочные знаки:False

-ThrottleLimit

Этот параметр ограничивает количество заданий, выполняемых одновременно. По мере запуска заданий они помещаются в очередь и ожидают, пока поток не будет доступен в пуле потоков для запуска задания. Ограничение по умолчанию — 5 потоков.

Размер пула потоков является глобальным для сеанса PowerShell. Указание ThrottleLimit в одном вызове задает ограничение для последующих вызовов в том же сеансе.

Тип:Int32
Position:Named
Default value:5
Обязательно:False
Принять входные данные конвейера:False
Принять подстановочные знаки:False

Входные данные

PSObject

Выходные данные

ThreadJob.ThreadJob