首页 > 解决方案 > 我的winforms上的Powershell开始睡眠冻结/阻止交互

问题描述

我正在尝试等待 10 秒,以便在我的脚本中执行命令。
问题是当我运行 start-sleep 时,我的界面会闪烁或阻塞窗口。
我尝试在不使用 start-sleep 的情况下执行特殊功能,但同样的事情发生了。

第一个解决方案(冻结/阻止交互窗口)

if ($Timeout -gt 0) {
   Start-Sleep -seconds $Timeout
}

第二种解决方案(冻结/阻止交互窗口)

if ($Timeout -gt 0) {
  Timeout $Timeout
}

function Timeout($seconds) {
    $doneDT = (Get-Date).AddSeconds($seconds)
    while($doneDT -gt (Get-Date)) {
        $secondsLeft = $doneDT.Subtract((Get-Date)).TotalSeconds
        write-host $secondsLeft
    }
 }

我怎么能在不冻结我的winforms的情况下超时代码执行?
谢谢

标签: winformspowershell

解决方案


我建议您为您的任务使用Start-Job(最简单)或运行空间(有点难但高效)来执行后台作业,这样您就不必依赖睡眠计时器来确保您的命令完成。但那是你的特权。

但是,您可以使用这个巧妙的小技巧(虽然并不理想)来解决您的无响应表单问题。使用下面的块来介绍 10 秒的延迟。

for ($i = 0; $i -lt 50; $i++)
{
    Start-Sleep -Milliseconds 200
    [System.Windows.Forms.Application]::DoEvents()
}

编辑:包括建议。当然,您可以在 WinForms 中执行此操作。我以前做过。Runspaces出于效率和资源的原因,我只是稍后再进行。但为了简单的目的,Start-Job是最简单的方法。

$ScriptBlock = {
    #super lengthy code enclosed in paranthesis to create a scriptblock
    #say takes a large amount of time to complete
}
$myJob = Start-Job -ScriptBlock $ScriptBlock

Do
{
    Start-Sleep -Milliseconds 100
    [System.Windows.Forms.Application]::DoEvents()
}
While ($myJob.State -ne "Completed")

$myJob | Receive-Job

现在你可以包括工作失败时的意外事件和其他东西,但我会让你弄清楚这一点。


推荐阅读