Отслеживать состояние пула Runspace из другого сеанса Runspace - PullRequest
0 голосов
/ 25 июня 2019

Я работаю над мастером графического интерфейса, этот мастер графического интерфейса будет собирать информацию от пользователя относительно его среды, а затем на последней странице инструмент вызовет 28 подписчиков в пуле Runspace.

Я хочу отслеживатьсостояние 28 подписчиков из другого пространства выполнения, как будто я наблюдаю за состоянием в пространстве выполнения GUI, графический интерфейс будет зависать.Проблема заключается в том, что когда я добавляю переменную Async в таблицу SyncHash и передаю ее в другое пространство выполнения, все состояние будет завершено равным true.

Есть ли у вас какие-либо идеи о том, как отслеживать состояние пула пространства выполненияиз другого пространства выполнения и предпримите действия, как только состояние всех 28 подписчиков будет завершено как истинное.

            #   Create RunspacePool.
            $RunspacePool = [RunspaceFactory]::CreateRunspacePool(1, [int]$env:NUMBER_OF_PROCESSORS + 1, $InitialSessionState, $Host)   #   Create Runspace Pool and add InitialSessionState to it
            $RunspacePool.ApartmentState = "MTA"  # Set Runspace Pool ApartmentState
            $RunspacePool.Open()    #   Open Runspace Pool
            $PSSessions = @()   #   Create an Array to add all PowerShell Session to it to use it when closing the sessions.

            #   Run a ForEach loop on all Subscript files and whith each iteration create a powershell session and call subscript.
            ForEach ($SubScript in $GuiHash.SubscriptFilePath) {
                $PowerShellSession = [powershell]::Create()
                $PowerShellSession.RunspacePool = $RunspacePool
                $AsyncHandle = $PowerShellSession.AddScript($SubScript).BeginInvoke()
                $PSSessions += [PSCustomObject] @{ 
                    Session = $PowerShellSession
                    Invoke = $AsyncHandle
                }
            }

Это выходные данные асинхронной формы из другого пространства выполнения, отображающие все как true

PS C:\Users\Administrator> Debug-Runspace  Runspace103
Debugging Runspace: Runspace103
To end the debugging session type the 'Detach' command at the debugger prompt, or type 'Ctrl+C' otherwise.

Stopped at: $Completed = ($GuiHash.PSSessions | Where-Object {$_.Invoke.IsCompleted -Eq $True}).Count
[DBG]: [Process:9212]: [Runspace103]: PS C:\Users\Administrator>> $GuiHash.PSSessions.invoke

CompletedSynchronously IsCompleted AsyncState AsyncWaitHandle                  
---------------------- ----------- ---------- ---------------                  
                 False        True            System.Threading.ManualResetEvent
                 False        True            System.Threading.ManualResetEvent
                 False        True            System.Threading.ManualResetEvent
                 False        True            System.Threading.ManualResetEvent
                 False        True            System.Threading.ManualResetEvent
                 False        True            System.Threading.ManualResetEvent
                 False        True            System.Threading.ManualResetEvent
                 False        True            System.Threading.ManualResetEvent
                 False        True            System.Threading.ManualResetEvent
                 False        True            System.Threading.ManualResetEvent
                 False        True            System.Threading.ManualResetEvent
                 False        True            System.Threading.ManualResetEvent
                 False        True            System.Threading.ManualResetEvent
                 False        True            System.Threading.ManualResetEvent
                 False        True            System.Threading.ManualResetEvent
                 False        True            System.Threading.ManualResetEvent
                 False        True            System.Threading.ManualResetEvent
                 False        True            System.Threading.ManualResetEvent
                 False        True            System.Threading.ManualResetEvent
                 False        True            System.Threading.ManualResetEvent
                 False        True            System.Threading.ManualResetEvent
                 False        True            System.Threading.ManualResetEvent
                 False        True            System.Threading.ManualResetEvent
                 False        True            System.Threading.ManualResetEvent
                 False        True            System.Threading.ManualResetEvent
                 False        True            System.Threading.ManualResetEvent
                 False        True            System.Threading.ManualResetEvent
                 False        True            System.Threading.ManualResetEvent



[DBG]: [Process:9212]: [Runspace103]: PS C:\Users\Administrator>> detach

1 Ответ

0 голосов
/ 25 июня 2019

Вот как я справился с тем, что вы пытаетесь сделать раньше, адаптировав к вашим потребностям:

$PowerShellSession = @()
$Jobs = @()
$Wait = @()

#Loop through online servers for this DC and create a process for each to patch that server (up to 10 at a time)
For($i = 0; $i -lt $GuiHash.SubscriptFilePath.Count; $i++){
    #Create scriptblock from file
    $SB = [scriptblock]::Create((Get-Content $GuiHash.SubscriptFilePath[$i]))
    #Create thread for server
    $PowerShellSession += [powershell]::Create()
    #Add the scripblock to be run in the thread
    $PowerShellSession[$i].AddScript($SB)|Out-Null
    #Assign the runspace pool to this runspace 
    $PowerShellSession[$i].RunspacePool = $RunSpacePool
    #Start the script within its runspace as ASync
    $Jobs += $PowerShellSession[$i].BeginInvoke()
    #Find its wait handle to track the job
    $Wait += $jobs[$i].AsyncWaitHandle
}

#Wait for all jobs to complete
If($Wait){[System.Threading.WaitHandle]::WaitAll($Wait)|Out-Null}

#Collect the jobs
$Results = For($i = 0; $i -lt $Jobs.count;$i++){
    $PowerShellSession[$i].EndInvoke($Jobs[$i])
}

Основное отличие состоит в том, что я фиксирую то, что вы назначаете как .AsyncWaitHandle свойство $Asynchandle для каждого потока в массиве, а затем приказывает PowerShell ждать завершения всех дескрипторов ожидания.

...