脚本在循环中执行以下步骤,假设两个步骤都需要很长时间才能完成:
$x = DoSomeWork;
Start-Job -Name "Process $x" { DoSomeMoreWork $x; };
步骤1阻止脚本,当然步骤2没有。 我可以通过控制台轻松监控循环的进度/状态和步骤1.
我还想做的是在批处理仍在执行时监控步骤2启动的作业的作业状态。
通常,可以从另一个会话“附加”或查询另一个PowerShell会话吗? (假设监视会话没有产生工作者会话)
答案 0 :(得分:4)
如果我关注你,那么你就无法在两个不同的控制台实例之间共享状态。也就是说,你想要的方式是不可能的。但是,您无法从同一会话中监视作业。您可以通过工作中的事件发出信号:
Start-Job -Name "bgsignal" -ScriptBlock {
# forward events named "progress" back to job owner
# this even works across machines ;-)
Register-EngineEvent -SourceIdentifier Progress -Forward
$percent = 0
while ($percent -lt 100) {
$percent += 10
# raise a new progress event, redirecting to $null to prevent
# it ending up in the job's output stream
New-Event -SourceIdentifier Progress -MessageData $percent > $null
# wait 5 seconds
sleep -Seconds 5
}
}
现在您可以选择使用Wait-Event [-SourceIdentifier Progress]
,Register-EngineEvent -SourceIdentifier Progress [-Action { ... }]
或普通的交互式Get-Event
来查看和/或处理来自同一会话的进度(或者如果您使用其他计算机)在远程服务器上启动了这项工作。)
如果在本地计算机上完成所有工作,那么完全有可能您不需要Jobs基础结构。在RunspaceFactory和PowerShell对象上查看我的一篇旧博客文章,获取基本脚本“threadpool”实现:
http://www.nivot.org/2009/01/22/CTP3TheRunspaceFactoryAndPowerShellAccelerators.aspx
希望这有帮助,
-Oisin
答案 1 :(得分:2)
状态易于监控:
$job = Start-Job -Name "Process $x" { DoSomeMoreWork $x }
$job.state
如果您不需要从函数中检索任何输出数据,那么您可以像这样写入输出:
$job = Start-Job {$i=0; while (1) { "Step $i"; $i++; Start-Sleep -sec 1 }}
while ($job.State -eq 'Running')
{
Receive-Job $job.id
}
如果您确实需要捕获输出,那么您可以使用我认为的进度流:
$job = Start-Job {$i=0; while (1) {
Write-Progress Activity "Step $i"; $i++; Start-Sleep -sec 1 }}
while ($job.State -eq 'Running') {
$progress=$job.ChildJobs[0].progress;
$progress | %{$_.StatusDescription};
$progress.Clear(); Start-Sleep 1 }