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