2010-07-24 15 views
23

Desidero parallelizzare alcune azioni di analisi dei file con l'attività di rete in PowerShell. Google Quick per esso, start-filo sembrava una soluzione, ma:Come funziona il threading in PowerShell?

Il termine 'start-thread' non è riconosciuto come il nome di un cmdlet, una funzione, file di script o un programma eseguibile. Controlla l'ortografia del nome o se è stato incluso un percorso, verifica che il percorso sia corretto e riprova.

La stessa cosa è accaduta quando ho provato a iniziare il lavoro.

Ho provato anche trafficando con System.Threading.Thread

[System.Reflection.Assembly]::LoadWithPartialName("System.Threading") 
#This next errors, something about the arguments I can't figure out from the documentation of .NET 
$tstart = new-object System.Threading.ThreadStart({DoSomething}) 
$thread = new-object System.Threading.Thread($tstart) 
$thread.Start() 

Quindi, penso che la cosa migliore sarebbe di sapere che cosa ho fatto di sbagliato quando uso start-filo, perché sembra di lavorare per gli altri. Io uso v2.0 e non ho bisogno di compatibilità verso il basso.

+0

** tl; dr: ** 'receive-job (wait-job ($ a = inizio-lavoro {" heyo! "})); remove-job $ a' o '$ a = start-job {" heyo! " }; wait-job $ a; ricevere-lavoro $ a; remove-job $ a' Nota anche che se chiami 'receive-job' prima che il lavoro sia finito, potresti non ottenere nulla. – Andrew

+0

Anche '(get-job $ a) .jobstateinfo.state;' – Andrew

risposta

28

PowerShell non ha un comando predefinito denominato Start-Thread.

V2.0, tuttavia, ha lavori PowerShell, che possono essere eseguiti in background e possono essere considerati l'equivalente di un thread. Hai a disposizione i seguenti comandi per lavorare con i lavori:

Name        Category Synopsis 
----        -------- -------- 
Start-Job       Cmdlet Starts a Windows PowerShell background job. 
Get-Job       Cmdlet Gets Windows PowerShell background jobs that are running in the current ... 
Receive-Job      Cmdlet Gets the results of the Windows PowerShell background jobs in the curren... 
Stop-Job       Cmdlet Stops a Windows PowerShell background job. 
Wait-Job       Cmdlet Suppresses the command prompt until one or all of the Windows PowerShell... 
Remove-Job      Cmdlet Deletes a Windows PowerShell background job. 

Ecco un esempio su come lavorarci. Per avviare un processo, utilizzare Start-Job e passare un blocco di script che contiene il codice che si desidera eseguire in modo asincrono:

$job = start-job { get-childitem . -recurse } 

Questo comando avvierà un lavoro, che ottiene tutti i bambini sotto la directory corrente in modo ricorsivo, e vi essere restituito immediatamente alla riga di comando.

è possibile esaminare la variabile $job per vedere se il lavoro è finito, ecc Se si desidera attendere per un lavoro da finire, l'uso:

wait-job $job 

Infine, per ricevere i risultati da un lavoro, uso:

receive-job $job 
+4

Start-Job avvia effettivamente una nuova sessione di Powershell ed è pesante. Non inizia una discussione. – ca9163d9

+0

Start-Job non acquisisce nessuno stato dell'ambiente, nessuna gente del posto, funzioni o importazioni di moduli, ha un sovraccarico enorme ed è una tipica API PowerShell succhiante. Sarebbe davvero utile se .NET TPL potesse essere usato con un po 'di dispacciamento per la strategia dello spazio di lavoro di PS –

8

non è possibile utilizzare le discussioni direttamente come questo, ma non può essere incolpato per aver tentato dato che una volta l'intera BCL giace di fronte a voi non è del tutto sciocco aspettarsi la maggior parte di esso per lavorare :)

PowerShell esegue scriptblocchi in pipeline che a loro volta richiedono lo spazio di esecuzione per eseguirli. Ho bloggato su come pubblicare i propri script MT qualche tempo fa per v2 ctp3, ma la tecnica (e API) è sempre la stessa. Gli strumenti principali sono i tipi [runspacefactory] e [powershell]. Date un'occhiata qui:

http://www.nivot.org/2009/01/22/CTP3TheRunspaceFactoryAndPowerShellAccelerators.aspx

Quanto sopra è il modo più leggero per avvicinarsi MT scripting. C'è il supporto per il lavoro in background in v2 tramite start-job, get-job ma ho pensato che tu lo abbia già notato e visto che sono abbastanza pesanti.

4

Ho un articolo sul blog su come è possibile multithread qualsiasi script PowerShell specificato.

http://ryan.witschger.net/?p=22

Enjoy!

+0

Questo script è fantastico! Grazie mille per la pubblicazione. – Sune

+6

Questo articolo non è più disponibile. –

+3

https://web.archive.org/web/20130127083728/http://ryan.witschger.net/?p=22 – Mick