Condividi tramite


Start-ThreadJob

Crea processi in background simili al Start-Job cmdlet .

Sintassi

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>]

Descrizione

Start-ThreadJob crea processi in background simili al Start-Job cmdlet . La differenza principale è che i processi creati vengono eseguiti in thread separati all'interno del processo locale. Per impostazione predefinita, i processi usano la directory di lavoro corrente del chiamante che ha avviato il processo.

Il cmdlet supporta anche un parametro ThrottleLimit per limitare il numero di processi in esecuzione contemporaneamente. Man mano che vengono avviati più processi, vengono accodati e attendere fino a quando il numero corrente di processi scende al di sotto del limite di limitazione.

Esempio

Esempio 1- Creare processi in background con un limite di thread pari a 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;...

Esempio 2: confrontare le prestazioni di Start-Job e Start-ThreadJob

In questo esempio viene illustrata la differenza tra Start-Job e Start-ThreadJob. I processi eseguono il Start-Sleep cmdlet per 1 secondo. Poiché i processi vengono eseguiti in parallelo, il tempo di esecuzione totale è di circa 1 secondo, più qualsiasi tempo necessario per creare i processi.

# 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

Dopo aver sottratto 1 secondo per il tempo di esecuzione, è possibile osservare che Start-Job la creazione di cinque processi richiede circa 4,8 secondi. Start-ThreadJob è 8 volte più veloce, richiedendo circa 0,6 secondi per creare cinque processi. I risultati possono variare nell'ambiente, ma il miglioramento relativo deve essere lo stesso.

Esempio 3- Creare processi con InputObject

In questo esempio il blocco di script usa la $input variabile per ricevere input dal parametro InputObject . Questa operazione può essere eseguita anche tramite pipe di oggetti a 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

Esempio 4 - Eseguire lo streaming dell'output del processo nell'host padre

Usando il parametro StreamingHost è possibile indicare a un processo di indirizzare tutto l'output dell'host a un host specifico. Senza questo parametro, l'output passa alla raccolta del flusso di dati del processo e non viene visualizzato in una console host finché non si riceve l'output dal processo.

Per questo esempio, l'host corrente viene passato all'uso Start-ThreadJob della $Host variabile automatica.

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>

Si noti che viene visualizzata la richiesta da Read-Host e si è in grado di digitare l'input. Viene quindi visualizzato il messaggio da Write-Warning . Il Receive-Job cmdlet restituisce tutto l'output del processo.

Esempio 5- Scaricare più file contemporaneamente

Il Invoke-WebRequest cmdlet può scaricare un solo file alla volta. Nell'esempio seguente viene Start-ThreadJob usato per creare più processi di thread per scaricare più file contemporaneamente.

$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
}

Parametri

-ArgumentList

Specifica una matrice di argomenti o valori di parametro per lo script specificato dai parametri FilePath o ScriptBlock .

ArgumentList deve essere l'ultimo parametro della riga di comando. Tutti i valori che seguono il nome del parametro vengono interpretati nell'elenco di argomenti.

Tipo:Object[]
Posizione:Named
Valore predefinito:None
Necessario:False
Accettare l'input della pipeline:False
Accettare caratteri jolly:False

-FilePath

Specifica un file di script da eseguire come processo in background. Immettere il percorso e il nome file dello script. Lo script deve trovarsi nel computer locale o in una cartella a cui il computer locale può accedere.

Quando si usa questo parametro, PowerShell converte il contenuto del file di script specificato in un blocco di script ed esegue il blocco di script come processo in background.

Tipo:String
Posizione:0
Valore predefinito:None
Necessario:True
Accettare l'input della pipeline:False
Accettare caratteri jolly:False

-InitializationScript

Specifica i comandi da eseguire prima dell'avvio del processo. Racchiudere i comandi tra parentesi graffe ({}) per creare un blocco di script.

Usare questo parametro per preparare la sessione in cui deve essere eseguito il processo. Ad esempio, è possibile usarlo per aggiungere funzioni e moduli alla sessione.

Tipo:ScriptBlock
Posizione:Named
Valore predefinito:None
Necessario:False
Accettare l'input della pipeline:False
Accettare caratteri jolly:False

-InputObject

Specifica gli oggetti utilizzati come input per il blocco di script. Consente anche l'input della pipeline. Usare la $input variabile automatica nel blocco di script per accedere agli oggetti di input.

Tipo:PSObject
Posizione:Named
Valore predefinito:None
Necessario:False
Accettare l'input della pipeline:True
Accettare caratteri jolly:False

-Name

Specifica un nome descrittivo per il nuovo processo. È possibile usare il nome per identificare il processo con altri cmdlet di processo, ad esempio il Stop-Job cmdlet .

Il nome descrittivo predefinito è "Job#", dove "#" è un numero ordinale incrementato per ogni processo.

Tipo:String
Posizione:Named
Valore predefinito:None
Necessario:False
Accettare l'input della pipeline:False
Accettare caratteri jolly:False

-ScriptBlock

Specifica i comandi da eseguire nel processo in background. Racchiudere i comandi tra parentesi graffe ({}) per creare un blocco di script. Usare la $Input variabile automatica per accedere al valore del parametro InputObject . Questo parametro è obbligatorio.

Tipo:ScriptBlock
Posizione:0
Valore predefinito:None
Necessario:True
Accettare l'input della pipeline:False
Accettare caratteri jolly:False

-StreamingHost

Questo parametro fornisce un modo thread-safe per consentire Write-Host all'output di passare direttamente all'oggetto PSHost passato. Senza di esso, Write-Host l'output passa alla raccolta del flusso di dati delle informazioni sul processo e non viene visualizzato in una console host fino al termine dell'esecuzione dei processi.

Tipo:PSHost
Posizione:Named
Valore predefinito:None
Necessario:False
Accettare l'input della pipeline:False
Accettare caratteri jolly:False

-ThrottleLimit

Questo parametro limita il numero di processi in esecuzione contemporaneamente. Quando i processi vengono avviati, vengono accodati e attendere che un thread sia disponibile nel pool di thread per eseguire il processo. Il limite predefinito è 5 thread.

Le dimensioni del pool di thread sono globali per la sessione di PowerShell. Se si specifica un oggetto ThrottleLimit in una chiamata, viene impostato il limite per le chiamate successive nella stessa sessione.

Tipo:Int32
Posizione:Named
Valore predefinito:5
Necessario:False
Accettare l'input della pipeline:False
Accettare caratteri jolly:False

Input

PSObject

Output

ThreadJob.ThreadJob