Я пишу сценарий в PowerShell V4 для Windows 8.1, который использует фоновые процессы и события. Я нашел кое-что немного странное. Вместо того, чтобы публиковать около 2500 строк моего сценария, я включил гораздо более короткую программу, которая демонстрирует странное поведение. Я ожидаю, что это что-то, что я делаю неправильно, но я не вижу, в чем проблема. Код выглядит следующим образом:
`
# Scriptblocks to simulate the background task and the action to
# take when an event is raised
[scriptblock] $MyScript = {
for ($i = 0;$i -lt 30;$i++)
{
[console]::writeline("This is a test - $i")
start-sleep -m 500
}
}
[scriptblock] $StateChanged = {
[console]::writeline("The state changed")
}
# Create a runspace pool
$RunspacePool = [RunspaceFactory]::CreateRunspacePool(1, [int] $env:NUMBER_OF_PROCESSORS + 1)
$RunspacePool.ApartmentState = "MTA"
$RunspacePool.Open()
# Create and start the background task to run
$PS = [powershell]::Create()
[void] $PS.AddScript($MyScript)
$PS.RunspacePool = $RunspacePool
$Asyncresult = $PS.BeginInvoke()
# Register an interest in the InvocationStateChanged event for
# the background task. Should the event happen (which it will)
# run the $StateChanged scriptblock
Register-ObjectEvent -InputObject $PS -EventName InvocationStateChanged -Action $StateChanged
# The loop that simulates the main purpose of the script
[int] $j = 0
while ($PS.InvocationStateInfo.State -eq [System.Management.Automation.PSInvocationState]::Running)
{
if ($j -eq 2)
{
[void] $PS.BeginStop($NULL, $NULL)
}
"Running: $j" | out-host
sleep -m 400
$j = $j + 1
}
sleep 10
`
По сути, все, что он делает, это создает пространство выполнения для запуска блока сценария powershell, и пока он работает, что-то еще происходит на переднем плане. Я моделирую, как кто-то нажимает кнопку или, по какой-либо причине, выполняется метод begintop для остановки фонового процесса. Это все работает, и фоновый процесс должным образом останавливается. Однако я зарегистрировал событие для фонового сценария PowerShell, который запускает блок сценария, когда фоновое задание меняет состояние. Странно то, что блок сценария вызывается дважды, и я не могу понять, почему.
Вот некоторый результат запуска скрипта:
E:\Test Programs>powershell -file .\strange.ps1
This is a test - 0
Running: 0
This is a test - 1
Running: 1
The state changed
Running: 2
The state changed
E:\Test Programs>
Как видите, он дважды отображает «Состояние изменено». Их разделяет доля секунды. Я поставил sleep 10
в конце, чтобы исключить возможность того, что именно остановка скрипта вызывает второе сообщение «Состояние изменилось».
Если кто-нибудь может объяснить, что не так, я был бы очень благодарен.