Fro*_* F. 10 powershell powershell-2.0 powershell-3.0
在PowerShell中,您可以使用add_NameOfEvent({scriptblock})对象的-method 订阅事件.这适用于像按钮等的Form对象.但是,当我尝试使用它时System.Timers.Timer它不起作用.这是为什么?样品:
$timer1 = New-Object System.Timers.Timer
$timer1.Interval = 2000
$timer1.add_Elapsed({ Write-Host "Timer1 tick" })
$timer2 = New-Object System.Timers.Timer
$timer2.Interval = 2000
Register-ObjectEvent -InputObject $timer2 -EventName Elapsed -Action { Write-Host "Timer2 tick" }
$timer1.Start()
$timer2.Start()
Run Code Online (Sandbox Code Playgroud)
$timer2将工作正常,但$timer1永远不会写入控制台.Timer与ex有什么不同.一个表单组件(该add_...方法的工作原理)?是否Timer在单独的线程中运行并因此写入"隐藏"控制台?
证明该方法适用于那些不熟悉它的人的表单组件:
PS > Add-Type -AssemblyName System.Windows.Forms
PS > $b = New-Object System.Windows.Forms.Button
PS > $b.add_click({ Write-Host "button" })
#Get-EventSubscriber won't show this event, but it's added
PS > $b.PerformClick()
button
Run Code Online (Sandbox Code Playgroud)
如果您尝试此代码:
$w = new-object 'System.Windows.Forms.Form'
$timer1 = New-Object System.Timers.Timer
$timer1.Interval = 2000
$timer1.add_Elapsed({ Write-Host "Timer1 tick" })
$timer1.SynchronizingObject = $w
$timer1.Start()
$w.ShowDialog()
Run Code Online (Sandbox Code Playgroud)
您将看到预期的行为,因为System.Timers.Timer可以与窗口表单同步(如在ac#代码中).
powershell控制台中的问题是计时器是在不同的线程中创建的,无法与控制台同步,因为它没有公开ISynchronizeInvoke表示用于编组间隔时间内发出的事件处理程序调用的对象的接口.
如果SynchronizingObject是null,处理该事件经过的调用方法从系统线程池中的线程.
IMO在场景后面Register-ObjectEvent创建一个系统线程池来完成事件处理程序调用.
我无法用手重新创建什么Register-ObjectEvent ,但我认为可以使用一些c#/ Pinvoke代码.
| 归档时间: |
|
| 查看次数: |
1430 次 |
| 最近记录: |