Powershell 线程与 C# 线程

问题描述

在 C# 中,当我想创建一个调用函数的线程时,我只需这样做。

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

我的目标是在 Powershell 中做同样的事情。没什么特别的,它的唯一目的是防止 GUI 冻结。但我就是找不到可行的解决方案。

目前,我只是想让运行空间做任何事情。 如果我把它放在一个按钮的点击事件中,什么都不会发生。

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

[void]$PowerShell.AddScript({

    $test = "test"
    Write-Host $test

})

$PowerShell.Invoke()

但是如果我在脚本块中放置了一个消息框,那么效果很好。当某些事情有效而某些事情无效时,这让我感到非常困惑。

如果您有一项任务,您必须调用一个函数来完成一些工作并更新 GUI。您将如何在自己的线程中调用函数,以便 GUI 在 Powershell 中工作时不会冻结?在 C# 中,我有上面发布的简单示例或使用 BackgroundWorker。

解决方法

如果我把它放在一个按钮的点击事件中

$PowerShell.Invoke()同步执行,所以根据定义它会阻塞直到你添加的脚本完成,所以它冻结 GUI。

什么都没发生。

Write-Host $test(在 PSv5+ 中)写入信息流(流编号 6),不是直接由 {{ 1}} 调用 - 仅 成功输出(流编号 .Invoke())是;见about_Redirection

此外,即使有成功输出,从事件处理程序输出到成功流也不会出现在控制台(终端)中。


如果您有一项任务,您必须调用一个函数来完成一些工作并更新 GUI。您将如何在自己的线程中调用该函数,以便 GUI 在 Powershell 中工作时不会冻结?

参见下面的WPF-based answer,它可以相对较少地适应 WinForms。