如果我運行下面的代碼,事件動作被執行:的PowerShell:招聘事件動作使用表單不執行
$Job = Start-Job {'abc'}
Register-ObjectEvent -InputObject $Job -EventName StateChanged `
-Action {
Start-Sleep -Seconds 1
Write-Host '*Event-Action*'
}
字符串「的事件動作」顯示。
如果我使用的一種形式,並通過點擊一個按鈕來啓動上面的代碼,
事件動作不執行:
[System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
$Form1 = New-Object Windows.Forms.Form
$Form1.Add_Shown({
$Form1.Activate()
})
$Button1 = New-Object System.Windows.Forms.Button
$Button1.Text = 'Test'
$Form1.Controls.Add($Button1)
$Button1.Add_Click({
Write-Host 'Test-Button was clicked'
$Job = Start-Job {'abc'}
Register-ObjectEvent -InputObject $Job -EventName StateChanged `
-Action {
Start-Sleep -Seconds 1
Write-Host '*Event-Action*'
}
})
$Form1.ShowDialog()
只有當我再次點擊該按鈕,第一個事件的行動執行。
隨着第三次單擊第二個事件操作執行等。
如果我快速連續多次點擊,結果是不可預知的。
此外,當我在右上角的關閉窗體與按鈕,
最後一個「開放」的事件動作被執行。
注意:對於測試PowerShell ISE中是優選的,因爲PS控制檯顯示
串只在某些情況下。
有人可以給我一個線索這裏發生了什麼?
在此先感謝!
nimizen。
感謝您的解釋,但我並不真正瞭解,爲什麼StateChanged事件未被觸發或對主腳本可見,直到對錶單執行了一些操作。我希望再次嘗試向我解釋。
我想完成的是一種使用PowerShell和Forms的多線程處理。
我的計劃是這樣的:
'
腳本顯示了形式提供給用戶。
用戶做一些輸入並點擊一個按鈕。 根據用戶的輸入,一組作業以Start-Job開始,併爲每個作業註冊一個StateChanged事件。
作業正在運行時,用戶可以在窗體上執行任何操作(包括通過按鈕停止作業),並在必要時重新繪製窗體。
該腳本會對窗體或其子控件觸發的任何事件作出反應。
此腳本還會響應每個作業的StateChanged事件。
當發生StateChanged事件時,將檢查每個作業的狀態,並且如果所有作業都處於「已完成」狀態,則會使用Receive-Job獲取作業的結果並顯示給用戶。
'
這一切工作除了StateChanged事件罰款不是主要的腳本可見。
以上是我最喜歡的解決方案,如果您有任何想法如何實現這一點,請讓我知道。
否則,我很可能會採取一種解決方法,它至少會給用戶帶來多線程的感覺。它是在下面的示例示出:
[System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
$Form1 = New-Object Windows.Forms.Form
$Form1.Add_Shown({
$Form1.Activate()
})
$Button1 = New-Object System.Windows.Forms.Button
$Button1.Text = 'Test'
$Form1.Controls.Add($Button1)
$Button1.Add_Click({
$Form1.Focus()
Write-Host 'Test-Button was clicked'
$Job = Start-Job {Start-Sleep -Seconds 1; 'abc'}
Do {
Start-Sleep -Milliseconds 100
Write-Host 'JobState: ' $Job.State
[System.Windows.Forms.Application]::DoEvents()
}
Until ($Job.State -eq 'Completed')
Write-Host '*Action*'
})
$Form1.ShowDialog()