簡體   English   中英

Powershell在完成的腳本中添加多線程

[英]Powershell adding multithreading to finished script

我得到了一個腳本,它工作正常,但是我想通過使用多線程來加快速度。 問題是,在不更改大量代碼的情況下很難做到這一點。 我希望避免使用具有新的單獨作用域的作業,但這似乎是不可能的。 另外,start-job真的很慢,它需要~~ 150毫秒才能開始執行。 有什么辦法可以避免工作,或者至少可以按預期使此腳本塊正常工作? (沒有雙功能,正確傳遞參數)

Param(
    [int]$arg1 = 2, [int]$arg2 = 3
)
$functionDoSomething = { 
    function doSomething($inp) { 
        return $inp + 10
    }
}

function doSomething($inp) { 
    return $inp + 10
}

# time: 1523337 ticks
Measure-Command {
    Start-Job -Name Job1 -InitializationScript $functionDoSomething -ScriptBlock {
        return doSomething ($arg1 + $arg2)
    } -ArgumentList $arg1, $arg2
    Wait-Job Job1
    $var2 = Receive-Job Job1 # result is 10, so arguements aren't passed correctly, trick with @($arg1, arg2) = the same result
}

# time: 6867 ticks
Measure-Command {
    $var3 = doSomething ($arg1 + $arg2) # result is 15
}
# Have no fear - Invoke-Parallel is here. Hoping that I can help steer you in the right direction. Let me show you some pseudo code that can point you in the right direction.

# You need a list of objects in which you want to perform an operation for
$listOfComputers = @(
'1'
'2'
'3'
)

# Pipe your array to Invoke-Parallel which takes care of opening threads depending on the amount of objects piped in. 
# If you want to control the amount of simultaneous threads simply help Invoke-Parallel -ShowWindow to see how
$results = $listOfComputers | Invoke-Parallel -ScriptBlock {
function doSomething($inp) 
{ 
    return [int]$inp + 10
}
if ($_ -eq '1') { Start-Sleep -Seconds 15; Write-Verbose 'Waited 15s' } # Adding this so you can see that this script block is running in a multi-threaded fashion
# $_ refers to the values inside of $listOfComputers
return doSomething ($_)
} -Verbose

$results

<# Notice how 11 comes up last 
12
13
11
#>

首先,查看Runspaces和RunSpacePool。 創建運行空間時,可以指定要加載的模塊(默認模塊除外)。 有關更多詳細信息,請參見http://www.get-blog.com/?p=189

$ScriptBlock = {
 param([string]$forinput)
  "Do something with $forinput"

   [PSCusomObject]@{
    Line1="Something"
    Line2="Something done to $forinput"
    }#end of custom object output

}#end script block

#Create Runspace pool, 100 min and max.
#Example data contained within $item.property
$RunspacePool = [RunspaceFactory]::CreateRunspacePool(100,100)
$RunspacePool.Open()
$Jobs = 
 foreach ( $item in $VariableContainsListOfInput)
 {
  $Job = [powershell]::Create().
  AddScript($ScriptBlock).
  AddArgument($item.property)
  $Job.RunspacePool = $RunspacePool

 [PSCustomObject]@{
  Pipe = $Job
  Result = $Job.BeginInvoke()
 }
}

DO{Start-sleep -seconds 1
}While($Jobs.Result.IsCompleted -contains $false)

#Loop through jobs, pipe EndInvoke data from runspace into Export-CSV
$(ForEach ($Job in $Jobs)
{ $Job.Pipe.EndInvoke($Job.Result) }) |
 Export-Csv -Path "$FullPath\$file" -NoTypeInformation
#clean up runspace
$RunspacePool.Close()
$RunspacePool.Dispose()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM