web-dev-qa-db-ja.com

ForEach-Object -Parallel内でカスタム関数を渡す方法

関数を渡す方法が見つかりません。ただの変数。

ForEachループ内に関数を配置しないアイデアはありますか?

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

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

enter image description here

3
smark91

解決策は、希望するほど簡単ではありません。

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 で拡張機能が議論されており、呼び出し側の状態をオンデマンドでスレッドにコピーすることをサポートしています、これにより、呼び出し元の機能が使用可能になります。

Auxなしで行うことに注意してください。 $funcDef変数と$function:CustomFunction = $using:function:CustomFunctionを使用して関数を再定義しようとすると魅力的ですが、$function:CustomFunctionscript block、また、$using:スコープを指定したスクリプトブロックの使用は明示的に禁止されています。

$function:CustomFunctionは、 namespace variable notation のインスタンスです。これにより、getの両方を行うことができます。関数(そのbody[scriptblock]インスタンスとして)およびtoset(定義)[scriptblock]または関数本体を含む文字列のいずれかを割り当てます。

4
mklement0