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

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

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

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 немного переборщило с этой задачей.

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


person dopi    schedule 29.12.2015    source источник


Ответы (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 auto):

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

    $s.Stop()
    Write-Host "Event was raised at $($e.SignalTime)"
}
person Mathias R. Jessen    schedule 29.12.2015
comment
Это очень помогает мне и решает мою главную проблему. Из-за очень специфического способа передачи объекта в новое пространство выполнения у меня все еще есть один вопрос. Есть ли аналогичный способ доступа и изменения переменных, определенных в исходном пространстве выполнения? - person dopi; 29.12.2015