PowerShell异步计时器事件不在测试控制台之外工作

前端之家收集整理的这篇文章主要介绍了PowerShell异步计时器事件不在测试控制台之外工作前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我有一个Power Shell脚本,它使用异步计时器事件(后台进程)来测量某个条件发生了多长时间,然后再采取适当的操作.
当我在PowerGUI中运行脚本时,这非常正常,但是当我使用点源运行脚本或通过批处理文件运行脚本时,Timer事件操作不会触发.

这是一段代码片段.

$timer = New-Object System.Timers.Timer
$timer.Interval = 10000  
$timer.AutoReset = $true  
$timeout = 0

$action = { 
    "timeout: $timeout" | Add-Content $loglocation
    <more stuff here>
    $timer.stop()
}  
$start = Register-ObjectEvent -InputObject $timer -SourceIdentifier TimerElapsed -EventName Elapsed -Action $action

$timer.start()

while(1)
{
    <do some testing here>
}

所以当它工作时,我会看到每10秒写入日志的“timeout:XX”输出.但这只发生在编辑器中运行时.当我通过批处理文件运行它没有任何反应(虽然我可以确认while循环处理正常).

所以我的问题是,当我在PowerGUI内部运行脚本而不是命令行时,为什么我的体验会有所不同?我的想法是范围或并行线程可能存在问题,但我不确定问题是什么.此外,我没有在任何函数或循环中运行这些事件.

调用脚本文件时,$action脚本块使用调用者的范围(父范围)执行,而不是脚本文件的范围(子范围).因此,脚本文件中定义的变量在$action脚本块中不可用,除非它们被定义为使用全局范围或dot-sourced(这将使它们在全局范围内可用).有关更多信息,请参见 this wonderful article.

假设以下代码包含在名为test.ps1的文件中.

$timer = New-Object System.Timers.Timer
$timer.Interval = 10000  
$timer.AutoReset = $false

$timeout = 100
$location = 'SomeLocation'
$sourceIdentifier = 'SomeIdentifier'

$action = { 
Write-Host "Timer Event Elapsed. Timeout: $timeout,Location: $location,SourceIdentifier: $sourceIdentifier"
$timer.stop()
Unregister-Event $sourceIdentifier
}  

$start = Register-ObjectEvent -InputObject $timer -SourceIdentifier $sourceIdentifier -EventName Elapsed -Action $action

$timer.start()

while(1)
{
 Write-Host "Looping..."
 Start-Sleep -s 5
}

从powershell控制台调用时,当执行$action脚本块时,它使用的变量将没有值.

./test.ps1

Timer Event Elapsed. Timeout:,Location:,SourceIdentifier:

如果在调用脚本之前定义$action脚本块中使用的变量,则在执行操作时值将可用:

$timeout = 5; $location = "SomeLocation"; $sourceIdentifier = "SomeSI"
./test.ps1

Timer Event Elapsed. Timeout: 5,Location: SomeLocation,SourceIdentifier: SomeSI

如果您对脚本进行点源,则脚本中定义的变量将在当前作用域中可用,因此当操作执行时,值将可用:

. ./test.ps1

Timer Event Elapsed. Timeout: 100,SourceIdentifier: SomeIdentifier

如果变量已在脚本文件的全局范围中声明:

$global:timeout = 100
$global:location = 'SomeLocation'
$global:sourceIdentifier = 'SomeIdentifier'

然后,当$action脚本块在父作用域中执行时,这些值将可用:

./test.ps1

Timer Event Elapsed. Timeout: 100,SourceIdentifier: SomeIdentifier

猜你在找的Bash相关文章