Решение не так просто, как можно было бы надеяться:
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 $_
}
Этот подход необходим, потому что - помимо текущего местоположения (рабочего каталога) и переменных среды (которые применяются в рамках всего процесса) - потоки, которые ForEach-Object -Parallel
создает, не видят состояние вызывающей стороны, особенно ни в отношении переменных, ни функций (а также не пользовательских дисков PS и импортированных модулей).
Начиная с PowerShell 7.0, обсуждается улучшение на GitHub для поддержки копирования состояния вызывающего в потоки по требованию , что сделает Доступны функции вызывающего абонента.
Обратите внимание, что обходится без доп. * Переменная $funcDef
и попытка переопределить функцию с помощью $function:CustomFunction = $using:function:CustomFunction
заманчива, но $function:CustomFunction
- это блок скриптов , и использование блоков скриптов с указанной областью действия $using:
явно запрещено.
$function:CustomFunction
является экземпляром нотации переменной пространства имен , которая позволяет вам одновременно получить функцию (ее тело как [scriptblock]
экземпляр) и установите (определите) его, присвоив либо [scriptblock]
, либо строку, содержащую тело функции.