自定义PowerShell cmdlet不支持多线程?

时间:2013-06-06 15:15:02

标签: multithreading powershell jobs cmdlets

在下面的代码块中,我尝试在3个单独的线程中运行Get-MyCmdlet,如果Get-MyCmdlet没有提供任何内容,每个线程都会打开一个google页面。

Get-MyCmdlet非常简单,它唯一能做的就是WriteObject(“hello world”); (在c#代码中定义)。

但是,除非我将Get-MyCmdlet更改为Get-Host(这是系统默认的cmdlet),否则脚本始终会打开一个Google页面。

是否因为自定义cmdlet不支持多线程?任何帮助将不胜感激!

cmdlet:

[Cmdlet(VerbsCommon.Get, "MyCmdlet ")]
public class GetMyCmdlet  : Cmdlet
{
    protected override void ProcessRecord()
    {
         WriteObject("hello world");
    }
}

脚本:

$ScriptBlock = { 

        $result = Get-MyCmdlet 

        if (!$result) {[System.Diagnostics.Process]::Start("http://www.google.com")}

        $name = ($result | get-member)[-1].name
        $result = $result.$name
        return $result
}

...

$threads = 3
    for ($i = 0; $i -lt $threads) {

        $running = @($jobs | Where-Object {$_.State -match 'Running'})

        Write-Host $running.length
        if ($running.length -lt $threads) {

            $jobs += Start-job -ScriptBlock $ScriptBlock


            $i = $i + 1

        } else {
            get-job | receive-job
            $finished = @($jobs | Where-Object ($_.State -match 'Completed'))  

            if ($finished) {
                $finished.getType()
                foreach($job in $finished) {
                    Receive-Job -keep $job | Out-File "Output$.txt"
                    $i = $i + 1
                    $finished.Remove($job)
                    Remove-Job -job $job
                }
            }  
        }   
    }

1 个答案:

答案 0 :(得分:1)

没有自定义cmdlet不是问题。我的猜测是问题是调用Get-MyCmdlet失败并显示错误因此未设置$ result并且感谢您启动浏览器。如果要检查作业的结果,您会看到错误消息。您可能需要确保作业初始化正确,以便您可以调用cmdlet。您可以使用-InitializationScript的{​​{1}}参数导入作业的模块。有关详细信息,请参阅hereherehere