I am creating a runspace pool that will have multiple runspaces starting an stopping at different times.
To keep track of this all of my runspaces go into a collection.
I am trying to register an object event for each one so that I can return information from the runspace to the user in the gui.
The part where I am having problems with is here:
$Global:RunspaceCollection
$Global:x = [Hashtable]::Synchronized(@{})
$RunspaceCollection = @()
[Collections.Arraylist]$Results = @()
$RunspacePool = [RunspaceFactory]::CreateRunspacePool(1,5)
$RunspacePool.Open()
$action = {
Foreach($Runspace in $Global:RunspaceCollection.ToArray()) {
If ($Runspace.runspace.iscompleted){
$results.add($runspace.powershell.endinvoke($Runspace.runspace))
$runspace.powershell.dispose()
$runspacecollection.remove($Runspace)
Write-Host "I AM WORKING"
test-return
}
}
Function Start-PasswordReset($username) {
$scriptblock = {
Param($userame)
start-sleep -Seconds 10
$Result = "I have reset" + $username
$result
}
$Powershell = [PowerShell]::Create().AddScript($ScriptBlock).AddArgument($username)
$Powershell.RunspacePool = $RunspacePool
[Collections.Arraylist]$Global:RunspaceCollection += New-Object -TypeName PSObject -Property @{
Runspace = $PowerShell.BeginInvoke()
PowerShell = $PowerShell
}
Register-ObjectEvent -InputObject $runspacecollection[0].Runspace -EventName statechanged -Action $Action
}
}
The code is failing on the register-objectevent line, currently I have hard coded 0 for testing, but that will be the current runspaces number in the final version. I don't know if I have made a small mistake, or have a fundamental lack of understanding of how this works, I'm open to both possibilities!
I see a few issue but your main is that the StateChanged event is an event on the RunspacePool.Powershell object inside your RunspaceCollection[index] and not on the RunspaceCollection.Runspace (the custom "Runspace" property of the PSObject you have created).
Set your runspace on the Powershell object as in:
$powershell = [PowerShell]::Create()
$powershell.RunspacePool = $runspacePool
$powershell.AddScript($scriptBlock).AddArgument($username)
$Global:runspaceCollection += @{
PowerShell = $powershell
Handle = $powershell.BeginInvoke()
}
And then declare your event as:
Register-ObjectEvent -InputObject $Global:runspaceCollection[0].PowerShell.RunspacePool -EventName StateChanged -Action $Action
After that, I don't think you intended to have the Start-Password reset function inside the "Action" function. Here is the complete code that worked for me:
$Global:RunspaceCollection
$Global:x = [Hashtable]::Synchronized(@{})
$RunspaceCollection = @()
[Collections.Arraylist]$Results = @()
$RunspacePool = [RunspaceFactory]::CreateRunspacePool(1, 5)
$RunspacePool.Open()
$action = {
Foreach ($Runspace in $Global:RunspaceCollection.ToArray()) {
If ($Runspace.runspace.iscompleted) {
$results.add($runspace.powershell.endinvoke($Runspace.runspace))
$runspace.powershell.dispose()
$runspacecollection.remove($Runspace)
Write-Host "I AM WORKING"
test-return
}
}
}
Function Start-PasswordReset($username) {
$scriptblock = {
Param($userame)
start-sleep -Seconds 10
$Result = "I have reset" + $username
$result
}
$powershell = [PowerShell]::Create()
$powershell.RunspacePool = $runspacePool
$powershell.AddScript($scriptBlock).AddArgument($username)
$Global:runspaceCollection += @{
PowerShell = $powershell
Handle = $powershell.BeginInvoke()
}
Register-ObjectEvent -InputObject $Global:runspaceCollection[0].PowerShell.RunspacePool -EventName StateChanged -Action $Action
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With