Suppose an object referenced in some PS code is known to have fired 100 events between Register-ObjectEvent
and Unregister-Event
. Expectation would be for the host code to receive 100 events. However, it sometimes receives fewer than 100, often times a lot less.
I see this consistently happening in Windows 7 with PS v3, v4 and v5.1. The simple test case posted below appears to work under Windows 10, yet the failures in Windows 7 make me wonder if there is maybe something fundamentally wrong with the whole approach.
[ EDIT ] The same happens in Windows 10 with PS v5.1, only less often than in Windows 7. It took a few thousand runs with $fired = 10000
for it to happen, but it eventually did. [ end EDIT ]
Minimal self-contained code to make it happen (shamelessly adapted from an answer here):
$src = @'
using System;
namespace Utils {
public static class StaticEventTest
{
public static event EventHandler Fired;
public static void RaiseFired()
{
if (Fired != null)
{
Fired(typeof(StaticEventTest), EventArgs.Empty);
}
}
}}
'@
Add-Type -TypeDefinition $src
$fired = 1000
$global:recvd = 0
$srcId = 'Fired'
$id = Register-ObjectEvent ([Utils.StaticEventTest]) Fired `
-SourceIdentifier $srcId -Action { $global:recvd++ }
for ($i = 1; $i -le $fired; $i++) {
[Utils.StaticEventTest]::RaiseFired()
}
Unregister-Event -SourceIdentifier $srcId
Receive-Job -Job $id -Wait -AutoRemoveJob
if ($fired -eq $global:recvd) {
("total {0} events" -f $fired)
} else {
("total {0} events fired - {1} received" -f $fired, $global:recvd)
}
Having the above saved as test.ps1
and run in a loop gives something like this (on Windows 7):
C:\etc>for /l %n in (1, 1, 10) do @powershell.exe -executionPolicy remoteSigned -file test.ps1
total 1000 events
total 1000 events
total 1000 events
total 1000 events fired - 391 received
total 1000 events
total 1000 events
total 1000 events fired - 59 received
total 1000 events
total 1000 events fired - 199 received
total 1000 events
Any insghts much appreciated.