为什么我的 WindowsForm 在执行循环时没有响应 [英] Why is my WindowsForm not responding while executing loop

查看:59
本文介绍了为什么我的 WindowsForm 在执行循环时没有响应的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这可能是一个很难回答的问题.我写了一个脚本来检查进程的响应属性.为了可视化脚本正在运行,我创建了一个 Windows 窗体,您可以在其中查看正在监视的进程.该脚本运行良好,但我无法对我的 winform 执行任何操作.无法最小化或关闭它,一旦我将光标移动到 windowsform,我的鼠标光标就会切换到沙漏符号.任何想法为什么?

This may be a question that is difficult to answer. I wrote a Script that checks the responding property of a process. to visualize that the script is running, i created a windows form where you can see which process is watched. The script runs perfectly, but I can't do anything with my winform. Can't minimize or close it, my mouse cursor switches to the hourglass symbol as soon as I move the cursor to the windowsform. any ideas why?

当我注释掉 while 循环时,winform 也没有响应

The winform is also not responding when I comment out the while loop

这是我的代码:

if ($ShowWindowsForm){
    $window = New-Object System.Windows.Forms.Form
    $window.text = "Process Watcher"
    $window.size = New-Object System.Drawing.Size(350,100) 
    $window.location = New-Object System.Drawing.Size(100,100) 
    $icon = [system.drawing.icon]::ExtractAssociatedIcon($PSHOME + "\powershell.exe")
    $window.Icon = $Icon
    $text = New-Object System.Windows.Forms.Label
    $text.Text = "Folgender Prozess wird überwacht:`n$target.exe"
    $text.location = New-Object System.Drawing.Size(10,10) 
    $text.AutoSize = $true
    $window.Controls.Add($text)
    $window.Show()
}
while (1) {
    sleep -Milliseconds 100
    if(!((get-process $target).Responding -eq $true)) {
    #do stuff
}

推荐答案

如果有人遇到和我一样的问题,我现在得到了答案.

I got the answer now, if anyone runs into the same problem as I have.

首先,如果你只是创建一个 GUI 并进行一些处理,它们使用相同的线程.例子:

First of all, if you just create a GUI and do some processing, they use the same thread. example:

# Windows Form    
$window = New-Object System.Windows.Forms.Form
$window.text = "Process Watcher"
$window.size = New-Object System.Drawing.Size(350,100) 
$window.location = New-Object System.Drawing.Size(100,100) 
$window.ShowDialog()

# Processing
while (1) { # Do Stuff }

由于 .ShowDialog() 方法,PowerShell 现在将显示 $window,但 Windows 窗体 ($window) 不会没有反应.这是因为您在显示 Windows 窗体对话框的同一线程中运行循环.

PowerShell will now show the $window because of the .ShowDialog() method, but the Windows Form ($window) won't be responsive. That's because you're running a loop in the same thread as you show the Windows-Form Dialog.

所以我们需要为循环创建一个后台任务,所以它有一个自己的线程.这就是 PowerShell 的 Start-Job cmdlet 的用途.

So we need to create a Background Task for the loop, so it has a thread for itself. That's what PowerShell's Start-Job cmdlet is for.

假设您正在监视一个进程,并希望在 Windows 窗体中对其进行可视化.您的代码将如下所示:

let's say you're monitoring a process, and want to visualize it in a Windows-Form. Your Code will look like this:

$target = "firefox"

# Job
Start-Job -argumentlist $target {
    param($target)
    while ((get-process $target).Responding) {Sleep -Milliseconds 100}
    if (!(get-process $target).Responding) {<# Do Stuff #>}
}

# Windows Form    
$window = New-Object System.Windows.Forms.Form
$window.text = "Process Watcher"
$window.size = New-Object System.Drawing.Size(350,100) 
$window.location = New-Object System.Drawing.Size(100,100) 
$window.ShowDialog()

使用此代码,您的 Windows-Form 负责,并且您的循环在后台执行.我还想通过此代码示例展示的是,您必须将在作业脚本块之外声明的变量传递给带有 -argumentlist 参数和 param() 语句.否则它不会工作.

with this code, your Windows-Form is responsible, and your loop is executing in the background. What i also want to show with this code example is, that you have to pass a variable which you declared outside the job scriptblock to the job with the -argumentlist Parameter and param() statement. otherwise it won't work.

我希望这个答案对某人有所帮助,因为谷歌并没有真正给出一个好的答案(或者我只是没有找到一个好的答案)

I hope this answer will help someone because google doesn't really give a good answer to this (or I just didn't find a good one)

这篇关于为什么我的 WindowsForm 在执行循环时没有响应的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆