在PowerShell中将子作业的状态传递给父作业

时间:2014-05-11 03:08:44

标签: powershell jobs

我有一个基于PowerShell的大型GUI实用程序,可以根据请求在后台运行不同的操作。当他们询问作业的状态时,他们可以通过如下代码看到它们:

Get-Job | foreach {
    $JobID = $_.Id
    $JobCaption = $script:JobList[$JobID]
    if ($JobCaption -ne $null) {
        $JobState = $_.JobStateInfo
        $JobProgress = $_.Progress
        $JobPercent = $JobProgress.PercentComplete
        $JobStatusDescription = $JobProgress.StatusDescription
        $lstJobStatus.Items.Add("$JobID`: $JobCaption is $JobState ($JobStatusDescription), $JobPercent%")
    }
}

这适用于直接作业的任务。但是,有些任务反过来会将子任务作为真正的工作,并围绕它提供一些支持代码。例如:

$Job = Start-Job -ScriptBlock { 
    # setup omitted
    $ijob = Convert-VHD -Path $VHDPath -DestinationPath $NewVHDPath -ComputerName $TargetServer -VHDType Dynamic -ErrorAction 'SilentlyContinue' -AsJob
    while ($ijob.State -eq "Running") {
        $ip = $ijob.Progress
        Write-Progress -Activity $ip.Activity -CurrentOperation $ip.CurrentOperation -PercentComplete $ip.PercentComplete -Status $ip.Status
        Start-Sleep -Seconds 5
    }
    # cleanup omitted
}

注意我有一个长时间运行的操作,所以我从中做了一个工作并保存它。那是外地工作的孩子。

如何将内部作业进度信息传递到外部作业状态检查?我在这里的代码似乎没有用。 (是的,我知道民意调查并不理想,但我不确定是否有更好的方法。)

1 个答案:

答案 0 :(得分:1)

最终,我确实必须使用Write-Progress - 最终代码(我并不为此感到骄傲)看起来像这样:

$child = Convert-VHD -Path $VHDPath -DestinationPath $NewVHDPath -ComputerName $TargetServer -VHDType Dynamic -ErrorAction 'SilentlyContinue' -AsJob
$child.Name = "... primary conversion work for $VHDPath"
Write-Progress -PercentComplete $child.Progress[-1].PercentComplete -Activity $child.ChildJobs[0].Progress[-1].Activity -Status $child.Progress[-1].StatusDescription
while ($child.State -eq 'NotStarted') {
    Start-Sleep -Seconds 5
}
while ($child.State -eq 'Running') {
    Write-Progress -PercentComplete $child.Progress[-1].PercentComplete -Activity $child.Progress[-1].Activity -Status $child.Progress[-1].StatusDescription
    Start-Sleep -Seconds 5
}
Write-Progress -PercentComplete $child.Progress[-1].PercentComplete -Activity $child.ChildJobs[0].Progress[-1].Activity -Status $child.Progress[-1].StatusDescription

状态检查代码现在如下所示:

function Add-ProgressToList {
    param (
        [object] $actingJob
    )
    $displayTitle = $actingJob.Name
    $JobID = $actingJob.Id
    $JobState = $actingJob.JobStateInfo
    $JobProgress = $actingJob.Progress[-1]
    $JobPercent = $JobProgress.PercentComplete
    $JobActivity = $JobProgress.Activity
    $JobStatusDescription = $JobProgress.StatusDescription
    if ($JobPercent -eq $null) {
        $lstJobStatus.Items.Add("$JobID`: $displayTitle is $JobState")
    } else {
        $lstJobStatus.Items.Add("$JobID`: $displayTitle is $JobState ($JobActivity : $JobStatusDescription), $JobPercent%")
    }
    foreach ($Child in $actingJob.ChildJobs) {
        Add-ProgressToList $Child
    }
}

function Update-JobList {
    Set-Cursor -Busy -Operation 'Updating job list...'
    Clear-Listbox $lstJobStatus
    Get-Job | foreach {
        Add-ProgressToList $_
    }
    $lstJobStatus.SelectedIndex = $lstJobStatus.Items.Count - 1
    $lstJobStatus.SelectedIndex = -1
    Set-Cursor -Normal
    $stsJobs.Text = Get-TabLastUpdateText
}

我停止了一份工作清单,因为我意识到我可以用描述性的方式使用工作名称。递归可以提升孩子的工作情况(实际上并没有发生这么多)。

相关问题