【问题标题】:Adding all module functions into foreach-Object -Parallel block将所有模块功能添加到 foreach-Object -Parallel 块中
【发布时间】:2021-07-27 15:15:45
【问题描述】:

我有一个我需要发出的 API 请求列表,我正在尝试使用 Foreach-Object -Parallel 来加速它:

$funcDef = ${function:Request-Something}.ToString()
$results = [System.Collection.ArrayList]@()

$requests | ForEach-Object -parallel {
    ${function:Request-Something} = $using:funcDef
    $null = ($using:results).add((Request-Something -request $_))
}

但是,Request-Something 从同一模块 APIHelpers.psm1 调用许多其他自定义函数

我需要一种方法将所有必要的功能添加到该脚本块中

我正在考虑构建一个将函数名称映射到函数文本的哈希表,但我无法弄清楚将变量传递给 $function 的语法:

$funcDefs = @{}
(Get-Command -Module APIHelpers).Name | ForEach-Object {
    $name = $_
    $funcDefs[$name] = ${function:$`{name`}} #This does NOT work, I can't figure out the syntax
}

一旦我建立了这个哈希表,我想我可以修改原始代码:

$requests | ForEach-Object -parallel {
    foreach ($funcName in $using:funcDefs.keys) {
        ${function:$funcName} = $using:funcDefs[$funcName]
    }
    $null = ($using:results).add((Request-Something -request $_))
}

【问题讨论】:

标签: powershell powershell-7.0


【解决方案1】:

${function:$`{name`}} #这个不行,我看不懂语法

您正在使用namespace variable notation,它只支持文字项名称。[1]

使用针对function: 驱动器的等效Get-Content 调用,它允许您使用变量:

$funcDefs[$name] = (Get-Content function:$name).ToString()

或者,您可以通过Invoke-Expression (iex) 走捷径,其中should generally be avoided, however: (Invoke-Expression "`${function:$name}").ToString()


退后一步:你不能在-Parallel 脚本块内调用Import-Module 吗?


请注意,作为未来的增强,正在考虑将调用者的状态复制到并行线程,这意味着调用者看到的所有函数也对线程隐式可用;见GitHub issue #12240


[1] 从某种意义上说,您不能使用变量名或表达式。正如this answer 中所讨论的那样,字面上指定的名称实际上 - 并且出乎意料地 - 被解释为 通配符模式

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-24
    • 1970-01-01
    • 2020-09-30
    • 1970-01-01
    • 2015-10-20
    • 1970-01-01
    相关资源
    最近更新 更多