简体   繁体   English

从另一个PowerShell运行空间管理对象和变量

[英]manage objects and variables from another PowerShell runspace

I am currently working with the System.Timers.Timer object in Powershell. 我目前正在使用Powershell中的System.Timers.Timer对象。

The Problem i have encountered is, that when you register to the "Elapsed" event 我遇到的问题是,当您注册到“ Elapsed”事件时

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

the scriptblock will run in a different Powershell Runspace / thread The problem here is, that i want to modify the timer object in the scriptblock and basically create a loop of shorter Intervals until it reaches x seconds and the script stops 脚本块将在不同的Powershell运行空间/线程中运行这里的问题是,我想修改脚本块中的计时器对象,并基本上创建一个较短间隔的循环,直到达到x秒并且脚本停止

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

I have found the option to define runspaces, but i am not sure if i can work with the timer object through a self defined runspace. 我已经找到了定义运行空间的选项,但是我不确定是否可以通过自定义运行空间使用计时器对象。 Also i think using runspaces is a bit over the top for this task. 我也认为使用运行空间在此任务的顶部有点过头。

Is there another (simpler) way to get this to work? 还有另一种(更简单的)方法可以使它起作用吗? If not, is it possible to manipulate the timer object through self defined runspaces? 如果不是,是否可以通过自定义运行空间来操作计时器对象? (i probably do this in a different way if i'd have to use runspaces, but it is nice to know for the future) (如果我必须使用运行空间,我可能会以其他方式执行此操作,但是很高兴知道将来)

The $timer itself is passed along as the first argument to the event handler as the sender . $timer本身作为第一个参数传递给事件处理程序,作为sender This populates the $Sender automatic variable inside the action block automatically. 这将自动在操作块内填充$Sender自动变量。

You can modify that object reference instead of dereferencing $timer directly: 您可以修改该对象引用,而不是直接取消引用$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"
    }
}

You can also override the variable names by defining a param block inside the Action scriptblock, first argument is always the sender, second argument is the EventArgs (equivalent to the $EventArgs auto variable): 您还可以通过在Action脚本块中定义一个param块来覆盖变量名称,第一个参数始终是发送者,第二个参数是EventArgs(相当于$EventArgs自动变量):

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

    $s.Stop()
    Write-Host "Event was raised at $($e.SignalTime)"
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM