我正在使用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个工作。
答案 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"
}
}
}
}