W programie PowerShell można subskrybować wydarzenie, korzystając z metody obiektu obiektu add_NameOfEvent({scriptblock})
. Działa to dobrze dla obiektów Form, takich jak przyciski itp. Jednak gdy próbowałem go z System.Timers.Timer
, to nie działało. Dlaczego? Próbka:Dlaczego add_EventName nie działa z Timerem?
$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()
$timer2
będzie działać dobrze, ale nigdy nie $timer1
napisać do konsoli. Co różni Timer
od np. komponent formularza (gdzie działa metoda add_...
)? Czy Timer
działa w oddzielnym wątku i z tego powodu pisze do "ukrytej" konsoli?
Dowód, że metoda działa z form-komponentów dla tych, którzy nie znają go:
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
+1 za dobrą odpowiedź. Przeczytałem o obiekcie synchronizującym przed zapytaniem, i domyślam się, że normalna metoda kontroli dodawania, którą można użyć do dodania formantu w formularzu, ustawia również właściwość syncronisingobiekt. Jednak musi istnieć zmienna/obiekt, którego mogę użyć do zsynchronizowania timera z konsolą. Uważam to za poprawną odpowiedź, ale poczekam kilka dni, aby oznaczyć ją na wypadek, gdyby ktoś mógł dostarczyć pełne rozwiązanie (bez tworzenia formy dummy) :-) –
Graimer Mam nadzieję, że @ x0n może przyjść, by dać lepszy, ma głęboką wiedzę na temat wciągania Power Shell. W każdym razie znalazłem twoje pytanie naprawdę interesujące! –