如何在 ForEach-Object -Parallel 中传递自定义函数

sma*_*k91 12 powershell powershell-core

我找不到传递函数的方法。只是变数。

没有将函数放在 ForEach 循环中的任何想法?

function CustomFunction {
    Param (
        $A
    )
    Write-Host $A
}

$List = "Apple", "Banana", "Grape" 
$List | ForEach-Object -Parallel {
    Write-Host $using:CustomFunction $_
}
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

mkl*_*nt0 16

解决方案并不像人们希望的那么简单:

function CustomFunction {
    Param ($A)
    "[$A]"
}

# Get the function's definition *as a string*
$funcDef = $function:CustomFunction.ToString()

"Apple", "Banana", "Grape"  | ForEach-Object -Parallel {
    # Define the function inside this thread...
    $function:CustomFunction = $using:funcDef
    # ... and call it.
    CustomFunction $_
}
Run Code Online (Sandbox Code Playgroud)

注意:此答案包含一个类似的解决方案,用于在脚本块中使用调用者范围内的ForEach-Object -Parallel脚本块。

  • 这种做法是必要的,因为-除了从当前位置(工作目录)和环境变量(适用工艺范围) -该线程ForEach-Object -Parallel创建也不会相对于变量或函数的(并且也没有看到来电者的状态,特别是既不自定义 PS 驱动器和导入模块)。

    • 更新:js2010 的有用答案显示了一个更直接的解决方案,它传递System.Management.Automation.FunctionInfo,通过 获得Get-Command,可以直接用 调用&。唯一的警告是原始函数应该是无副作用的,即应该仅基于参数或管道输入运行,而不依赖于调用者的状态,特别是它的变量,因为这可能会导致线程安全问题。上面的字符串化技术隐式地防止了对调用者状态的任何有问题的引用,因为函数体是在每个线程的上下文中重建的。
  • 从 PowerShell 7.1 开始,GitHub 上正在讨论一项增强功能,以支持按需将调用者的状态复制到线程,这将使调用者的功能可用。

注意凑合不用aux。$funcDef变量并尝试用 with 重新定义函数$function:CustomFunction = $using:function:CustomFunction很诱人,但它$function:CustomFunction是一个脚本块,并且$using:明确禁止使用带有作用域说明符的脚本块。

$function:CustomFunctionnamespace variable notation 的一个实例,它允许您通过分配 a或包含函数体的字符串来获取函数(其主体作为[scriptblock]实例)并设置(定义)它[scriptblock]

  • 这对于一次性来说非常好,但是如果您导入了多个模块,定义了更多函数,变量悬而未决,基本上是一整套纸牌,那就太麻烦了,而且太容易出错。希望 PowerShell Core 团队决定将运行空间复制作为一个选项。 (3认同)

sha*_*202 6

我通过在循环内使用 include 通过 ps1 文件添加了一整套自定义函数来并行进程。这使事情变得非常干净整洁。

ForEach-Object -Parallel {
    # Include custom functions inside parallel scope
    . $using:PSScriptRoot\CustomFunctions.ps1
    # Now you can reference any function defined in the file
    My-CustomFunction
    ....
Run Code Online (Sandbox Code Playgroud)

这确实会产生需要在每个并行进程中加载​​函数的开销,但就我而言,这与整体处理时间的关系微乎其微。