Function PowerShell-为什么我的按钮在while循环期间不可单击?

Function PowerShell-为什么我的按钮在while循环期间不可单击?,function,powershell,loops,while-loop,click,Function,Powershell,Loops,While Loop,Click,这是我的职责: Function StartProgress { $x = 600 $length = $x / 100 while($x -gt 0) { $min = [int](([string]($x/60)).split('.')[0]) $lblCnt.Text = " " + $min + " minutes " + ($x % 60) + " seconds left" $pbrCnt.Value =

这是我的职责:

Function StartProgress
{
    $x = 600
    $length = $x / 100
        while($x -gt 0) {
        $min = [int](([string]($x/60)).split('.')[0])
        $lblCnt.Text = " " + $min + " minutes " + ($x % 60) + " seconds left"
        $pbrCnt.Value = $pbrCnt.Maximum - $x
        Start-Sleep -Seconds 1
        $x--
        }
}
我在这里补充说:

$timer.add_Tick({StartProgress})

在主窗体中,有一个按钮在我的while循环中不可单击。为什么?

在一个while循环中,应用程序没有时间触发更新。如果不抛出更新(PropertyChangedEvent等),用户界面将不会收到更改数据的通知。

在一个while循环中,您的应用程序不会有时间触发更新。如果不抛出更新(PropertyChangedEvent等),用户界面将不会收到已更改数据的通知。

如前所述,使用
启动睡眠强制同步睡眠将阻止整个用户界面线程,并使表单无响应

不要使用
启动睡眠
,而是让计时器周期性地调用您的函数
,每秒一次;然后,您需要使用脚本级别变量跟踪您的状态:

$script:x = 600

Function StartProgress {
  $length = $script:x / 100
  $min = [int](([string]($script:x / 60)).split('.')[0])
  $lblCnt.Text = " " + $min + " minutes " + ($script:x % 60) + " seconds left"
  $pbrCnt.Value = $pbrCnt.Maximum - $script:x
  if (--$script:x -eq 0) { $timer.Dispose() }
}

$timer.Interval = 1000 # 1 sec.
$timer.add_Tick({StartProgress})
$timer.Start()

注意当
$script:x
达到
0
时,如何在
$timer
上调用
.Dispose()
,以防止生成更多事件;如果处理提前停止,则必须手动调用
$timer.Dispose()

如前所述,使用
Start sleep
强制同步睡眠会将UI线程作为一个整体阻止,并使窗体无响应

不要使用
启动睡眠
,而是让计时器周期性地调用您的函数
,每秒一次;然后,您需要使用脚本级别变量跟踪您的状态:

$script:x = 600

Function StartProgress {
  $length = $script:x / 100
  $min = [int](([string]($script:x / 60)).split('.')[0])
  $lblCnt.Text = " " + $min + " minutes " + ($script:x % 60) + " seconds left"
  $pbrCnt.Value = $pbrCnt.Maximum - $script:x
  if (--$script:x -eq 0) { $timer.Dispose() }
}

$timer.Interval = 1000 # 1 sec.
$timer.add_Tick({StartProgress})
$timer.Start()

注意当
$script:x
达到
0
时,如何在
$timer
上调用
.Dispose()
,以防止生成更多事件;如果处理提前停止,则必须手动调用
$timer.Dispose()

我的理解是,除非编写代码添加多线程,否则GUI是单线程的。这意味着一切都在等待任何循环。我不这么认为。如果我删除了
开始睡眠-秒1
,那么我可以单击我的按钮,但是
$min
会出错。您的函数会强制一切等待。。。当您消除延迟时,您只需缩短一切必须等待的时间。您建议我如何让按钮工作?从我对GUI代码的理解来看,您需要将阻止GUI的任何内容放入一个循环中,该循环旨在频繁更新GUI。。。或者把阻塞代码放到另一个线程中。。。或者切换到c#。查看一下运行空间或PoshRSJob模块,了解如何使用运行空间。我的理解是,除非您编写代码添加多线程,否则GUI是单线程的。这意味着一切都在等待任何循环。我不这么认为。如果我删除了
开始睡眠-秒1
,那么我可以单击我的按钮,但是
$min
会出错。您的函数会强制一切等待。。。当您消除延迟时,您只需缩短一切必须等待的时间。您建议我如何让按钮工作?从我对GUI代码的理解来看,您需要将阻止GUI的任何内容放入一个循环中,该循环旨在频繁更新GUI。。。或者把阻塞代码放到另一个线程中。。。或者切换到c#。查看一下运行空间或PoshRSJob模块,了解如何使用运行空间。如何更改代码以使按钮工作?如何更改代码以使按钮工作?