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 驱动器和导入模块)。
System.Management.Automation.FunctionInfo
,通过 获得Get-Command
,可以直接用 调用&
。唯一的警告是原始函数应该是无副作用的,即应该仅基于参数或管道输入运行,而不依赖于调用者的状态,特别是它的变量,因为这可能会导致线程安全问题。上面的字符串化技术隐式地防止了对调用者状态的任何有问题的引用,因为函数体是在每个线程的上下文中重建的。从 PowerShell 7.1 开始,GitHub 上正在讨论一项增强功能,以支持按需将调用者的状态复制到线程,这将使调用者的功能可用。
注意凑合不用aux。$funcDef
变量并尝试用 with 重新定义函数$function:CustomFunction = $using:function:CustomFunction
很诱人,但它$function:CustomFunction
是一个脚本块,并且$using:
明确禁止使用带有作用域说明符的脚本块。
$function:CustomFunction
是namespace variable notation 的一个实例,它允许您通过分配 a或包含函数体的字符串来获取函数(其主体作为[scriptblock]
实例)并设置(定义)它[scriptblock]
。
我通过在循环内使用 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)
这确实会产生需要在每个并行进程中加载函数的开销,但就我而言,这与整体处理时间的关系微乎其微。
归档时间: |
|
查看次数: |
3204 次 |
最近记录: |