问题描述
在 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。