问题
I can't find a way to pass the function. Just variables.
Any ideas without putting the function inside the ForEach loop?
function CustomFunction {
Param (
$A
)
Write-Host $A
}
$List = "Apple", "Banana", "Grape"
$List | ForEach-Object -Parallel {
Write-Host $using:CustomFunction $_
}
回答1:
The solution isn't quite as straightforward as one would hope:
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 $_
}
This approach is necessary, because - aside from the current location (working directory) and environment variables (which apply process-wide) - the threads that
ForEach-Object -Parallel
creates do not see the caller's state, notably neither with respect to variables nor functions (and also not custom PS drives and imported modules).As of PowerShell 7.0, an enhancement is being discussed on GitHub to support copying the caller's state to the threads on demand, which would make the caller's functions available.
Note that making do without the aux. $funcDef
variable and trying to redefine the function with $function:CustomFunction = $using:function:CustomFunction
is tempting, but $function:CustomFunction
is a script block, and the use of script blocks with the $using:
scope specifier is explicitly disallowed.
$function:CustomFunction
is an instance of namespace variable notation, which allows you to both get a function (its body as a [scriptblock]
instance) and to set (define) it, by assigning either a [scriptblock]
or a string containing the function body.
回答2:
I just figured out another way using get-command, which works with the call operator. $a ends up being a FunctionInfo object. EDIT: I'm told this isn't thread safe, but I don't understand why.
function hi { 'hi' }
$a = get-command hi
1..3 | foreach -parallel { & $using:a }
hi
hi
hi
来源:https://stackoverflow.com/questions/61273189/how-to-pass-a-custom-function-inside-a-foreach-object-parallel