Search code examples
c#multithreadingpowershellrunspace

Powershell threading vs C# threading


In C# when I want to create a thread which calls a function I simply do this.

Thread t = new Thread(() => calledFunction());
t.Start();

My goal is to do the same thing in Powershell. Nothing fancy, its only purpose is the prevent the GUI from freezing up. But i just cant find a working solution.

At the moment, I'm just trying to make the runspace to do anything. If I put this inside a click event of a button nothing happens.

$Runspace = [runspacefactory]::CreateRunspace()
$PowerShell = [powershell]::Create()
$PowerShell.runspace = $Runspace
$Runspace.Open()

[void]$PowerShell.AddScript({

    $test = "test"
    Write-Host $test

})

$PowerShell.Invoke()

But if I put a messagebox in the scriptblock then that works fine. It's very confusing to me when some things works and some things doesn't.

If you had a task where you had to call a function that does some work and updates a GUI. How would you go about calling that function in its own thread so that the GUI won't freeze while it's working in Powershell? In C# I have the easy example I posted above or using a BackgroundWorker.


Solution

  • If I put this inside a click event of a button

    $PowerShell.Invoke() executes synchronously, so it will by definition block until the script you've added completes, so it will freeze the GUI.

    nothing happens.

    Write-Host $test (in PSv5+) writes to the information stream (stream number 6), which is not directly returned by an .Invoke() call - only success output (stream number 1) is; see about_Redirection.

    Additionally, even if there were success output, outputting to the success stream from an event handler will not surface in the console (terminal).


    If you had a task where you had to call a function that does some work and updates a GUI. How would you go about calling that function in its own thread so that the GUI won't freeze while it's working in Powershell?

    See the following WPF-based answer, which can be adapted to WinForms with relatively little effort.