Powershell作业执行正确处理批处理,无需等待整批完成

时间:2018-04-28 14:17:26

标签: powershell powershell-v3.0

我正在使用PowerShell作业并行处理活动。我在下面附上了一个示例代码。

Function Wait-UntilJobFailOrSuccess {
    [CmdletBinding()]
    param(
        [Parameter(ValueFromPipeline)]
        [System.Management.Automation.Job[]]$Job
    )
    begin {
        $jobs = @()
        $abort = $false
    }
    process {
        $jobs += $Job
    }
    end {

        while ('Running' -In $jobs.State) {
            if ('Failed' -in $jobs.State) {
                $jobs | Stop-Job 
                $abort = $true
                break
            }
            Start-Sleep -Milliseconds 500
        }

        foreach ($job in $jobs) {
            if ($job.State -eq 'Failed') {
                $job.ChildJobs | ForEach-Object {
                    Write-Host ($_.JobStateInfo.Reason.Message) -ForegroundColor Red
                }
            }
            else {

                Write-Host "$($job.Name) $($job.State) successfully"
            }
        }

        if ($abort) {
            exit 1
        }
    }
}

上述方法将用于并行执行的作业。

$packageSpecs | ForEach-Object -Begin {
    $job = @()
} -Process {
    $builditem = $_ 
   $job += Start-Job -Name $("Pack" + $builditem.name) -ScriptBlock $scriptoExecute -ArgumentList $args
    if ($job.Count -eq $maxNumberOfThread) {
        $job |Wait-UntilJobFailOrSuccess
        $job = @()
    }
} -End {

    if ($job.Count -gt 0) {
        $job |Wait-UntilJobFailOrSuccess
        $job = @()
    }

}

如果您看到上面的代码我正在根据计算机中存在的CPU数运行作业,$ maxNumberOfThread包含系统中允许的逻辑进程数。

现在我将告诉你我的问题陈述。

假设$ maxNumberOfThread = 4。它将一次处理4个工作。我想要的是,如果我正在处理4份工作,而且任何工作都已完成。我应该能够排队下一个。目前正处理下一批所有4个工作。

1 个答案:

答案 0 :(得分:0)

我做了一些调整,我删除了Wait-UntilJobFailOrSuccess函数。但这应该有效。试试让我知道。如果它有效,那么你可以根据你的功能进行调整。

 $packageSpecs | ForEach-Object -Begin {
     $job = @()
 } -Process {
     $builditem = $_ 
     $job += Start-Job -Name $("Pack" + $builditem.name) -ScriptBlock $scriptoExecute -ArgumentList $args
     $running = @($job | Where-Object { $_.State -eq 'Running' })
     if ($running.Count -ge $maxNumberOfThread) {
         $running | Wait-Job -Any | Out-Null
         Write-Verbose "Waiting on jobs" -Verbose
     }  

 } -End {

     if ($job.Count -gt 0) {
         $job |Wait-UntilJobFailOrSuccess
         $job = @()
     }
 }

我对你的功能进行了一些修改,请告诉我它是如何工作的。该函数现在需要传递给它的$ MaxNumberOfThread。

Function Wait-UntilJobFailOrSuccess {
    [CmdletBinding()]
    param(
        [Parameter(ValueFromPipeline)]
        [System.Management.Automation.Job[]]$Job,

        [Parameter()]
        [int]$maxNumberOfThread
    )
    begin {
        $jobs = @()
        $abort = $false
    }
    process {
        $jobs += $Job
        foreach ($j in $Jobs) {
            $running = @($jobs | Where-Object { $_.State -eq 'Running' })
            if ($running.Count -ge $maxNumberOfThread) {
                if ('Failed' -in $jobs.State) {
                    $jobs | Stop-Job 
                    $abort = $true
                    break
                }
                else {
                    $running | Wait-Job -Any | Out-Null
                    Write-Verbose "Waiting on jobs" -Verbose
                }
            }
            if ($abort) {
                exit 1
            }
        }
    }
    end {
        foreach ($j in $jobs) {
            if ($j.State -eq 'Failed') {
                $j.ChildJobs | ForEach-Object {
                    Write-Host ($_.JobStateInfo.Reason.Message) -ForegroundColor Red
                }
            }
            else {

                Write-Host "$($j.Name) $($j.State) successfully"
            }
        }       
    }
}