从Powershell Parallel Foreach循环返回值

时间:2015-03-11 19:22:27

标签: powershell parallel-processing powershell-v3.0

我试图在Powershell中编写以下情况:

Create array of objects

Parallel foreach of array
{
     Perform work on item of array;
     Assign/return value of work;
}

Perform work on results of Parallel foreach loop

我无法找到关于如何做到这一点的明确指南,我自己和其他两个同事似乎无法将其编译成一个可行的解决方案,甚至是一个简单的示例解决方案,我们可以然后适用于我们需要做的实际工作。

给出一个简单的任务,比如接收一组int:

$inputArray = @(1..200)

然后,对于每个int,将它自身相乘,并以线程安全的方式返回每个乘法的值(我假设,数组),您将如何在Powershell中对此进行编码?

编辑:不要混淆任何可能的答案,但这是我们迄今为止尝试创建的内容。

$inputArray = @()
$resultArray = @()

for($i = 0; $i -le 10; $i++)
{
    $inputArray += Get-Random
}

Write-Output "Workflow"

workflow ExampleWorkflow
{
    param ($items)

    $test = @()

    foreach -Parallel ($item in $items)
    {
        $WORKFLOW:test += ($item * $item)
        $WORKFLOW:test += ($item + $item)
        $WORKFLOW:test += ($item * 3.14)
    }
    Write-Output ("TEST CURRENT: " + $test[0])
}

ExampleWorkflow $inputArray

Write-Output ("This is test: " + $test)

$resultArray | % { Write-Output $_ }

2 个答案:

答案 0 :(得分:2)

我并不是100%明确你的最终目标是什么,但是从你发布的代码看起来你试图随机化数组中的值并从随机值中创建一个新数组。如果是这样,请尝试下面的内容。 $ resultArray之前没有填充,因为它是在工作流程之外进行初始化的。

$inputArray = @()


for($i = 0; $i -le 10; $i++)
{
    $inputArray += Get-Random
}

Write-Output "Workflow"

workflow ExampleWorkflow
{
    param ($items)

    $test = @()

    foreach -Parallel ($item in $items)
    {
        $WORKFLOW:test += ($item * $item)
        $WORKFLOW:test += ($item + $item)
        $WORKFLOW:test += ($item * 3.14)

    }
    [array]$resultArray = @($test)
    Write-Output ("TEST CURRENT: " + $test[0])
    $resultArray


}




ExampleWorkflow $inputArray 

答案 1 :(得分:0)

我已经在许多场景中测试了并行模式下的循环行为。测试表明,每个循环调用都会创建自己的变量空间,就像在函数内部一样,问题是在并行模式下同时编辑同一个对象。对我来说,当我使用一种接受并行写入表的机制(即在 SQL 中)执行此操作时,我写入一个表的并行循环按预期工作

    $_ARRAY = $null
    $_ARRAY = @()
    $_ARRAY = @{
            col1 = $somthing1
            col2 = $somthing1
    }
    
    Function _pull_to_SQL($_ARRAY){
        $DB = "DBName"
        $SQLSRVR = "Server\Instance"
        $TABLE = "TableName"
        $SQLCON = New-Object System.Data.SqlClient.SqlConnection("Data Source=$SQLSRVR; `
                    Initial Catalog=$DB;Integrated Security=SSPI")
        $SQLCON.open()
        $SQL = $SQLCON.CreateCommand() 
        $INSERT = "INSERT INTO $TABLE (col1,col2) VALUES ('$($_ARRAY.col1)','$($_ARRAY.col2)')"
        $SQL.CommandText = $INSERT
        $SQL.ExecuteNonQuery() > $null
        $SQLCON.Close()
    }

在并行模式下编辑的表中的 -ThrottleLimit 参数为空并且在循环内它包含循环中仅单个调用的值后,因此循环中的每个执行都是单独执行的。

在并行模式下编辑的数组在退出循环后将始终为空。