PowerShell: Threading Enhancements FTW!

To build on the threading library I mentioned here, I've added some functionality to make it easier to communicate with the seperate thread. Still, keep in mind that PowerShell will only allow one pipeline to be executing in a runspace at any given time. So, these new functions can only be used while the thread is inactive. But, they provide power into setting up the thread to be run and communicating with the original runspace.

The new functions are as follows:

Get-ThreadVariable - Accesses available variables from within the thread.
Set-ThreadVariable - Sets a variable for use within the thread.
Invoke-ThreadExpression - Allows synchronous execution of a script block within the thread.

I also updated the Join-Thread function to include an optional -timeout parameter so that you could return control back if the thread didn't complete in the desired time. I also updated the Running property to IsRunning and changed it so that it will only return true while the asynchronous invoke command is executing.

With this new example you can do even more now, as shown here.

$thread = New-Thread
Invoke-ThreadExpression $thread { function foo($bar) { echo "$bar!" } }
Set-ThreadVariable $thread "name" "PowerShell Rocks"
Start-Thread -thread $thread { $value = foo $name } | Out-Null
Join-Thread $thread
Get-ThreadVariable $thread "value"

This should return "PowerShell Rocks!" when Get-ThreadVariable is called. I've already used this script to multi-thread our Exchange backup from a single script. It is working quite nicely (nice as in have cut our 8 hour backup down to 4 hours) and I can already imagine several other wonderful places it will be used.

3 Comments

  • How can I run a function asyncly? The code

    $thread = Start-Thread {
    & Myfunction 5
    }

    doesn't work. Help!

  • You need to use the Invoke-ThreadExpression function to put the function in the new thread (runspace).

    Invoke-ThreadExpression $thread { function foo($bar) { echo "$bar!" } }
    Set-ThreadVariable $thread "name" "PowerShell Rocks"Start-Thread -thread $thread { $value = foo $name } | Out-Null

  • Great Article! I am trying to use it.

    Inside a [ScriptBlock]:

    1. How can I call the cmdlets (e.g Add-Item) without getting "Cannot invoke this function because the current host does not impl
    ement it." error?

    2. Can I load in assembly (like Microsoft.SqlServer.Smo) and use the objects in that assembly?

    Thanks!

Comments have been disabled for this content.