【问题标题】:Powershell background threads and return valuesPowershell后台线程和返回值
【发布时间】:2019-05-22 11:16:50
【问题描述】:

我无法让后台线程在 Powershell 中工作。我想使用运行空间,我可以在其中插入一个脚本并在有脚本时获取更新,并允许我的主线程处理它需要的数据。我不确定为什么这段代码不返回正确的值?我测试的所有服务器在没有在运行空间中使用时都返回 true,但这里的返回值为 0。

我对使用 powershell 作业不感兴趣。

$servers = @("x1","x2","x3");
$results = New-Object Collections.Generic.List[String];
$input = New-Object 'System.Management.Automation.PSDataCollection[psobject]'
$output = New-Object 'System.Management.Automation.PSDataCollection[psobject]'
$results.Clear();
foreach ($server in $servers)
{
    Write-Host $server;
    $powerShell = [Management.Automation.PowerShell]::Create();
    [Void]$PowerShell.AddScript({
        $result = Test-Connection $server -Count 1 -Quiet; 
        return ($server - $result)
    })

    $handle = $powerShell.BeginInvoke($input,$output);
    $results.Add($output);
}

$results;

或

$results = New-Object Collections.Generic.List[String];
$input = New-Object 'System.Management.Automation.PSDataCollection[psobject]'
$output = New-Object 'System.Management.Automation.PSDataCollection[psobject]'
$results.Clear();
foreach ($server in $servers)
{
    Write-Host $server;
    $powerShell = [Management.Automation.PowerShell]::Create();
    [Void]$PowerShell.AddScript({
        param ($server)
        $result = Test-Connection $server -Count 1 -Quiet; 
        return ($server - $result)
    })

    $handle = $powerShell.BeginInvoke($server,$output);
    #$handle = $powerShell.BeginInvoke($input,$output);
    $results.Add($output);
}

$results;

【问题讨论】:

  • 你看过jobs。这些旨在在后台运行任务。
  • 是的,我对使用作业不感兴趣

标签: multithreading powershell runspace


【解决方案1】:

玩得开心。

$servers = @("x1","x2","x3");
$input   = New-Object 'System.Management.Automation.PSDataCollection[psobject]'
$output  = New-Object 'System.Management.Automation.PSDataCollection[psobject]'

$GH = [hashtable]::Synchronized(@{})

[System.Collections.Generic.List[PSObject]]$GH.results = @()
[System.Collections.Generic.List[PSObject]]$jobs = @()

$initialSessionState = [System.Management.Automation.Runspaces.InitialSessionState]::CreateDefault()

$runspacePool = [RunspaceFactory]::CreateRunspacePool(1, ([int]$env:NUMBER_OF_PROCESSORS + 1), $initialSessionState, $host )
$runspacePool.ApartmentState = 'MTA'
$runspacePool.ThreadOptions  = "ReuseThread"
[void]$runspacePool.Open()

$jobCounter = 1

foreach ($server in $servers)
{
    Write-Host $server;

    $job = [System.Management.Automation.PowerShell]::Create($initialSessionState)
    $job.RunspacePool = $runspacePool

    $scriptBlock = { param ( [hashtable]$GH, [string]$server ); $result = Test-Connection $server -Count 1 -Quiet; $GH.results.Add( [PSObject]@{ 'Server' = $server; 'Result' = $result } ) }

    [void]$job.AddScript( $scriptBlock ).AddArgument( $GH ).AddArgument( $server )
    $jobs += New-Object PSObject -Property @{
                                    RunNum = $jobCounter++
                                    JobObj = $job
                                    Result = $job.BeginInvoke() }

    do {
        Sleep -Seconds 1 
    } while( $runspacePool.GetAvailableRunspaces() -lt 1 )

}

Do {
    Sleep -Seconds 1
} While( $jobs.Result.IsCompleted -contains $false)


$GH.results;


$runspaces = Get-Runspace | Where { $_.Id -gt 1 }

foreach( $runspace in $runspaces ) {
    try{
        [void]$runspace.Close()
        [void]$runspace.Dispose()
    }
    catch {
    }
}

[void]$runspacePool.Close()
[void]$runspacePool.Dispose()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-10-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多