Управлять объектами и переменными из другого пространства выполнения PowerShell

В настоящее время я работаю с объектом System.Timers.Timer в Powershell.

Проблема, с которой я столкнулся, заключается в том, что когда вы регистрируетесь на событие Elapsed

Register-ObjectEvent -InputObject $timer -EventName Elapsed -SourceIdentifier ThirtySecTimer -Action $scriptblock

блок сценария будет работать в другом пространстве / потоке выполнения Powershell. Проблема в том, что я хочу изменить объект таймера в блоке сценария и создать цикл с более короткими интервалами, пока он не достигнет x секунд, и сценарий не прекратится.

$action={
    $timer.stop()
    Show-MsgBox -Prompt "time's up" #selfdefined function using Windows Forms
    $timer.interval=$interval - 1000
    $timer.start()
}

Я нашел опцию для определения пространств выполнения, но я не уверен, смогу ли я работать с объектом таймера через само определенное пространство выполнения. Кроме того, я думаю, что использование runspaces является немного чрезмерным для этой задачи.

Есть ли другой (более простой) способ заставить это работать? Если нет, возможно ли манипулировать объектом таймера через самостоятельно определенные пространства выполнения? (Я, вероятно, делаю это по-другому, если бы мне пришлось использовать пространства для выполнения, но это приятно знать на будущее)

1 ответ

Решение

$timer сам передается в качестве первого аргумента обработчику событий, как sender, Это заполняет $Sender автоматическая переменная внутри блока действия автоматически.

Вы можете изменить ссылку на этот объект вместо разыменования $timer непосредственно:

# Create a timer starting at a 10 second interval
$timer = New-Object System.Timers.Timer
$timer.Interval = 10000

# Register the event handler
Register-ObjectEvent $timer Elapsed timersourceid -Action {
    Write-Host "Event triggered at $(Get-Date|Select-Object -ExpandProperty TimeOfDay)"

    $Sender.Stop()
    if($Sender.Interval -ge 1000)
    {
        $Sender.Interval = $Sender.Interval - 1000
        $Sender.Start()
    }
    else
    {
        Write-Host "Timer stopped"
    }
}

Вы также можете переопределить имена переменных, определив блок param внутри блока сценария Action, первый аргумент всегда является отправителем, второй аргумент - EventArgs (эквивалентно $EventArgs автоматическая переменная):

Register-ObjectEvent $Timer Elapsed SourceId -Action {
    param($s,$e)

    $s.Stop()
    Write-Host "Event was raised at $($e.SignalTime)"
}
Другие вопросы по тегам