PowerShell: действие события задания с формой не выполнено

Если я запускаю следующий код, выполняется действие события:

$Job = Start-Job {'abc'}
Register-ObjectEvent -InputObject $Job -EventName StateChanged `
    -Action {
             Start-Sleep -Seconds 1
             Write-Host '*Event-Action*'
            } 

Строка '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()

Ответы на вопрос(2)

Ваш ответ на вопрос