Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/powershell/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Multithreading Powershell:接收作业中出现意外结果_Multithreading_Powershell_Start Job_Powershell Jobs - Fatal编程技术网

Multithreading Powershell:接收作业中出现意外结果

Multithreading Powershell:接收作业中出现意外结果,multithreading,powershell,start-job,powershell-jobs,Multithreading,Powershell,Start Job,Powershell Jobs,我正试图更好地了解powershell如何处理作业 这两篇文章都帮了大忙: 但是,在下面的示例脚本中,我在调用Receive Job时得到了意外的结果。我希望每行都有一个结果,但有时我会看到每行都有多个结果或额外的空白回车。有没有关于如何只写出从每个作业的控制台流入的信息的想法 $loops = 1..10 $jobs = new-object System.Collections.ArrayList $loops | % { $jobs.add( (star

我正试图更好地了解powershell如何处理作业

这两篇文章都帮了大忙:

但是,在下面的示例脚本中,我在调用Receive Job时得到了意外的结果。我希望每行都有一个结果,但有时我会看到每行都有多个结果或额外的空白回车。有没有关于如何只写出从每个作业的控制台流入的信息的想法

$loops = 1..10
$jobs = new-object System.Collections.ArrayList

$loops | % {
    $jobs.add( 
        (start-job -ScriptBlock {
            param($list)
            $list | % {
                sleep -seconds (get-random -Maximum 3 -Minimum 1)
                write-host "Number is: $_"
            }
        } -ArgumentList (,$loops))
    ) | out-null
}


while ($jobs.count -gt 0)
{
    if ($jobs -ne $null)
    {
        $list = $jobs | ? { $_.HasMoreData -eq $true }
        $list | % { Receive-Job -Job $_ }
        $list2 = $jobs.Clone() | ? { $_.State -eq "Completed" }
        $list2 | % {
            $jobs.Remove($_) | out-null
        }
        $list = $null
    }
}
输出可以是

Number is: 1 Number is: 1 Number is: 2 电话号码是:1 电话号码是:1 电话号码是:2 或者有时候

Number is: 1 Number is: 2 Number is: 1Number is: 2 Number is: 1Number is: 2Number is: 2 电话号码是:1 电话号码是:2 号码是:1号码是:2 数字是:1数字是:2数字是:2
你把这件事复杂化了很多。您不需要所有这些循环来手动处理事情。您应该利用可用的cmdlet。这将实现您想要的基本功能:

$loops = 1..10

$scriptBlock = {
  param($list)
  $list | % {
    sleep -seconds (get-random -Maximum 3 -Minimum 1)
    write-host "Number is: $_"
  }
}

$jobs = $loops | % { start-job -ScriptBlock $scriptBlock -ArgumentList (,$loops) }

$jobs | Wait-Job | Receive-Job
然而,这将把所有的输出组合在一起,而不知道什么工作做了什么。事实上,您使用的是
Write Host
,这意味着您实际上无法访问数据,它只是打印到屏幕上

如果要实际存储或处理生成的作业输出,可以执行以下操作:

$loops = 1..10

$scriptBlock = {
  param($list)
  $list | % {
    sleep -seconds (get-random -Maximum 3 -Minimum 1)
    "Number is: $_"  # don't use write-host, just output the string
  }
}

$jobs = $loops | % { start-job -ScriptBlock $scriptBlock -ArgumentList (,$loops) }

$jobs | Wait-Job  # wait for all jobs to be complete
$jobs |%{
   $output = $_ | Receive-Job
   # process $output here, do what you want with it
}

谢谢你说得对,我把剧本复杂化了。我倾向于在实验中这样做。您的示例运行得非常好,但如果我希望在作业运行时获取数据,而不是调用wait job,该怎么办?例如,我试图在作业运行时(这是脚本底部所有循环的点)将任何输出(通过写主机)从作业管道传输到主powershell控制台。通过这样做,我是否走上了“这不是工作的目的/功能”的道路?是否所有作业都要等待完成后才能调用
接收作业
?并不是说这不是作业的“目的”,只是这不是它们最擅长的,也不是您拥有cmdlet支持的目的。您可以执行各种疯狂的循环和完成检查,并获得一些“流”行为的外观,但这将非常复杂且容易出错。这是你的成本/收益决定。作业最擅长的是“我会去做这项工作,当我完成后,你可以处理结果。”如果你想要流式处理,你可以让每个作业写入不同的日志文件,然后启动“尾部”流程来流式处理每个日志。谢谢你,你帮了我很大的忙。在处理一些使用作业的示例项目时,我会记住您的建议。