Как передать пользовательскую функцию внутри ForEach-Object -Parallel - PullRequest
2 голосов
/ 17 апреля 2020

Я не могу найти способ передать функцию. Просто переменные.

Любые идеи без помещения функции в ForEach l oop?

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

$List = "Apple", "Banana", "Grape" 
$List | ForEach-Object -Parallel {
    Write-Host $using:CustomFunction $_
}

enter image description here

1 Ответ

2 голосов
/ 17 апреля 2020

Решение не так просто, как можно было бы надеяться:

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], либо строку, содержащую тело функции.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...