我的 Powershell 脚本不执行多线程工作,为什么? [英] my Powershell script doesn't do multi-thread job , why?

查看:130
本文介绍了我的 Powershell 脚本不执行多线程工作,为什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

#my 脚本摘自

#my script is a excerpt of https://www.codeproject.com/Tips/895840/Multi-Threaded-PowerShell-Cookbook #the first example #the issue is where ".AddScript($secb)" is. All jobs are finished sequentially , Could anyone explain ??? #why in my script , .AddScript($sb) is concurrent ??



$numThreads = 5
# Create session state
$myString = "this is session state!"
$sessionState = [System.Management.Automation.Runspaces.InitialSessionState]::CreateDefault()
$sessionstate.Variables.Add((New-Object -TypeName System.Management.Automation.Runspaces.SessionStateVariableEntry -ArgumentList "myString" ,$myString, "example string"))
   
# Create runspace pool consisting of $numThreads runspaces
$RunspacePool = [RunspaceFactory]::CreateRunspacePool(1, 5, $sessionState, $Host)
$RunspacePool.Open()

$Jobs = @()
$sb={
param ($data)
$r=Get-Random
Write-Host "before $r"
Start-Sleep -Seconds 3
Write-Host "after $r"
}
$secb={
param ($block)
Invoke-Command -ScriptBlock $block
}
1..5 | % {
    #below line is not concurrent  , i don't know why
    $Job = [powershell]::Create().AddScript($secb) # $Job = [powershell]::Create().AddScript($sb) could do multi-thread
    $Job.AddArgument($sb)

    $Job.RunspacePool = $RunspacePool
    $Jobs += New-Object PSObject -Property @{
      RunNum = $_
      Job = $Job
      Result = $Job.BeginInvoke()
   }
}
 
Write-Host "Waiting.." -NoNewline
Do {
   Write-Host "." -NoNewline
   Start-Sleep -Seconds 1
} While ( $Jobs.Result.IsCompleted -contains $false) #Jobs.Result is a collection

解决方案

I'm by far not an expert on RunSpaces, usually whenever I need multithreading I use the ThreadJob module. I'm not sure what you are doing wrong in your code but I can show you a working example for what you're trying to do. I took this example from this answer (credits to Mathias) which is excellent and modified it a bit.

Code:

cls
$elapsedTime = [System.Diagnostics.Stopwatch]::StartNew()

$numThreads = 5
# Create session state
$myString = "this is session state!"
$sessionState = [System.Management.Automation.Runspaces.InitialSessionState]::CreateDefault()
$sessionstate.Variables.Add((New-Object -TypeName System.Management.Automation.Runspaces.SessionStateVariableEntry -ArgumentList "myString" ,$myString, "example string"))
   
# Create runspace pool consisting of $numThreads runspaces
$RunspacePool = [RunspaceFactory]::CreateRunspacePool(1, 5, $sessionState, $Host)
$RunspacePool.Open()

$runspaces = foreach($i in 1..5)
{
    $PSInstance = [powershell]::Create().AddScript({
        param ($TestNumber)

        Write-Output "Test Number: $TestNumber"

        $r={Get-Random}

        Write-Output "before $(& $r)"
        Start-Sleep -Seconds 3
        Write-Output "after $(& $r)"

    }).AddParameter('TestNumber',$i)

    $PSInstance.RunspacePool = $RunspacePool

    [pscustomobject]@{
        Instance = $PSInstance
        Result = $PSInstance.BeginInvoke()
    }
}
 
while($runspaces|Where-Object{-not $_.Result.IsCompleted})
{
    Start-Sleep -Milliseconds 500
}

$resultRunspace = [collections.generic.list[string]]::new()

$Runspaces|ForEach-Object {
    $resultRunspace.Add($_.Instance.EndInvoke($_.Result))
}

$elapsedTime.Stop()
"Elapsed Time: {0}" -f $elapsedTime.Elapsed.TotalSeconds
""
$resultRunspace

Result:

Elapsed Time: 3.1271587

Test Number: 1 before 474010429 after 2055432874
Test Number: 2 before 1639634857 after 1049683678
Test Number: 3 before 72786850 after 2046654322
Test Number: 4 before 1958738687 after 1832326064
Test Number: 5 before 1944958392 after 1652518661

Now, again, if you are able to install modules I would recommend ThreadJob as it is a lot easier to use and performs equally as fast as RunSpaces.

I wrote a script some time ago which would loop through all the directories in $HOME and get the number of files on each one, the script was meant to compare Linear Loops vs ThreadJob vs RunSpace here are the results and why I would always recommend ThreadJob

这篇关于我的 Powershell 脚本不执行多线程工作,为什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆