I have been writing a script in PowerShell V4 on Windows 8.1 which makes use of background processes and
events. I have found something which is a little strange. Rather than post the 2,500 lines or so of my
script I have included a much shorter program which exhibits the odd behaviour. I expect it is something
I am doing wrong but I cannot see what the problem is. The code is as follows:
# Scriptblocks to simulate the background task and the action to # take when an event is raised [scriptblock] $MyScript = { for ($i = 0;$i -lt 30;$i++) { [console]::writeline("This is a test - $i") start-sleep -m 500 } } [scriptblock] $StateChanged = { [console]::writeline("The state changed") } # Create a runspace pool $RunspacePool = [RunspaceFactory]::CreateRunspacePool(1, [int] $env:NUMBER_OF_PROCESSORS + 1) $RunspacePool.ApartmentState = "MTA" $RunspacePool.Open() # Create and start the background task to run $PS = [powershell]::Create() [void] $PS.AddScript($MyScript) $PS.RunspacePool = $RunspacePool $Asyncresult = $PS.BeginInvoke() # Register an interest in the InvocationStateChanged event for # the background task. Should the event happen (which it will) # run the $StateChanged scriptblock Register-ObjectEvent -InputObject $PS -EventName InvocationStateChanged -Action $StateChanged # The loop that simulates the main purpose of the script [int] $j = 0 while ($PS.InvocationStateInfo.State -eq [System.Management.Automation.PSInvocationState]::Running) { if ($j -eq 2) { [void] $PS.BeginStop($NULL, $NULL) } "Running: $j" | out-host sleep -m 400 $j = $j + 1 } sleep 10
Essentially all it does is create a runspace to run a powershell scriptblock and while that is running something
else happens in the foreground. I simulate someone pressing a button or, for whatever reason, a beginstop method
being executed to stop the background process. That all works and the background process duly stops. However,
I have registered an event for the background powershell script which runs a scriptblock when the background
job changes state. The strange thing is that the scriptblock gets invoked twice and I cannot work out why.
Here is some output from running the script:
E:\Test Programs>powershell -file .\strange.ps1 This is a test - 0 Running: 0 This is a test - 1 Running: 1 The state changed Running: 2 The state changed E:\Test Programs>
As you can see it displays “The state changed” twice. They are a fraction of a second apart. I put a
sleep 10 at the end to eliminate the possibility that it is the script stopping that is causing the
second “The state changed” message.
If anyone can explain what is wrong I would be very grateful.