ForEach-Object - Parallel에서 사용자 지정 함수를 전달하는 방법
저는 그 기능을 전달할 방법을 찾을 수가 없습니다.변수만.
ForEach 루프 안에 기능을 넣지 않은 아이디어가 있습니까?
function CustomFunction {
Param (
$A
)
Write-Host $A
}
$List = "Apple", "Banana", "Grape"
$List | ForEach-Object -Parallel {
Write-Host $using:CustomFunction $_
}
솔루션은 원하는 만큼 간단하지 않습니다.
# Sample custom function.
function Get-Custom {
Param ($A)
"[$A]"
}
# Get the function's definition *as a string*
$funcDef = ${function:Get-Custom}.ToString()
"Apple", "Banana", "Grape" | ForEach-Object -Parallel {
# Define the function inside this thread...
${function:Get-Custom} = $using:funcDef
# ... and call it.
Get-Custom $_
}
참고: 이 답변에는 의 호출자 범위에서 스크립트 블록을 사용하는 것과 유사한 솔루션이 포함되어 있습니다.ForEach-Object -Parallel
스크립트 블록입니다.
참고: 기능이 모듈 자동 로딩 기능으로 알려진 위치 중 하나에 있는 모듈에 정의되어 있다면 기능 호출은 그대로 작동합니다.
ForEach-Object -Parallel
, 별도의 노력 없이 각 스레드에서 모듈을 가져오는 데 드는 비용이 implicit으로 발생합니다.현재 위치(작업 디렉토리)와 환경 변수(프로세스 전체에 적용되는)를 제외하고는 다음과 같은 스레드가 필요하기 때문에 위와 같은 접근 방식이 필요합니다.
ForEach-Object -Parallel
create는 호출자의 상태를 볼 수 없으며, 변수나 함수(사용자 지정 PS 드라이브 및 가져온 모듈)에 대해서도 볼 수 없습니다.PowerShell 7.2.x에서는 GitHub 이슈 #12240에서 요구 시 호출자의 상태를 병렬 스레드에 복사할 수 있도록 지원하는 향상된 기능이 논의되고 있으며, 이를 통해 호출자의 기능을 자동으로 사용할 수 있습니다.
문자열을 통해 각 스레드의 함수를 재정의하는 것은 aux 없이 수행하기 위한 시도로서 매우 중요합니다.$funcDef
변수를 사용하여 함수를 다시 정의하려고 합니다.${function:Get-Custom} = ${using:function:Get-Custom}
실패한다, 왜냐하면${function:Get-Custom}
는 스크립트 블록이며 스크립트 블록을 사용합니다.$using:
스코프 지정자는 교차 thread(교차 실행 공간) 문제를 방지하기 위해 명시적으로 허용되지 않습니다.
하지만,
${function:Get-Custom} = ${using:function:Get-Custom}
을 사용할 수 있습니다. 예를 들어 이 답변을 참조하십시오.현재 구문적으로 다음 작업을 수행할 수 있는 에서 작동하지 않습니다.
& ${using:function:Get-Custom} $_
,왜냐면${using:function:Get-Custom}
스크립트 블록으로 보존됩니다(와 함께 unlike).Start-Job
, 문자열로 역직렬화되는 경우, 그 자체로 놀라운 동작입니다 - GitHub issue #11698 참조).즉, 교차 스레드를 직접적으로 사용하는 것입니다.[scriptblock]
사례들은 불분명한 실패를 야기하고, 그 이유는 이유입니다.ForEach-Object -Parallel
그것을 애초에 막습니다.이와 유사한 허점으로 인해 스레드 간 문제가 발생합니다.
ForEach-Object -Parallel
호출자 범위에서 얻은 command-info 개체를 사용하고 있습니다.Get-Command
각 나사산의 기능체로서$using:
스코프: 이 또한 방지해야 하지만 PowerShell 7.2.7 이후는 아닙니다. 이 게시물 및 GitHub 이슈 #16461을 참조하십시오.
${function:Get-Custom}
는 namespace 변수 표기법의 한 예로, 함수를 둘 다 얻을 수 있습니다(body as a[scriptblock]
instance) 및 a를 할당하여 설정(define)합니다.[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
....
이로 인해 각 병렬 프로세스에서 기능을 로드해야 하는 오버헤드가 발생하지만, 제 경우에는 전체 처리 시간과 관련된 작은 문제였습니다.
방금 get-command를 사용하는 다른 방법을 알아냈어요 통화 교환원과 함께 작동하는 거죠$a는 결국 함수가 됩니다.정보 개체.
편집: 이것이 실 안전하지 않다고 들었는데, 왜 그런지 이해가 안 됩니다.
function hi { 'hi' }
$a = get-command hi
1..3 | foreach -parallel { & $using:a }
hi
hi
hi
그래서 저는 함수를 동적으로 추가하려는 사람들에게 유용할 수 있는 또 다른 작은 방법을 알아냈습니다. 특히 함수가 배열되어 있을 때와 같이 함수의 이름을 미리 알지 못할 수도 있습니다.
# Store the current function list in a variable
$initialFunctions=Get-ChildItem Function:
# Source all .ps1 files in the current folder and all subfolders
Get-ChildItem . -Recurse | Where-Object { $_.Name -like '*.ps1' } |
ForEach-Object { . "$($_.FullName)" }
# Get only the functions that were added above, and store them in an array
$functions = @()
Compare-Object $initialFunctions (Get-ChildItem Function:) -PassThru |
ForEach-Object { $functions = @($functions) + @($_) }
1..3 | ForEach-Object -Parallel {
# Pull the $functions array from the outer scope and set each function
# to its definition
$using:functions | ForEach-Object {
Set-Content "Function:$($_.Name)" -Value $_.Definition
}
# Call one of the functions in the sourced .ps1 files by name
SourcedFunction $_
}
이것의 주된 "꼼수"는 다음을 사용하는 것입니다.Set-Content
와 함께Function:
기능 이름과 더불어 PowerShell은 기본적으로 각 항목을 처리합니다.Function:
오솔길로서
이것은 당신이 다음의 출력을 고려할 때 타당합니다.Get-PSDrive
. 각 항목은 동일한 방식(즉, 콜론과 함께)으로 "드라이브"로 사용될 수 있기 때문입니다.
언급URL : https://stackoverflow.com/questions/61273189/how-to-pass-a-custom-function-inside-a-foreach-object-parallel
'programing' 카테고리의 다른 글
PowerShell에서 XML용 하위 요소를 추가하는 방법 (0) | 2023.11.05 |
---|---|
Swift에서 UIViewController 하위 클래스의 사용자 지정 이니셜라이저를 만드는 방법은 무엇입니까? (0) | 2023.11.05 |
Javascript/Angular JS에서 반올림하는 방법 -- 그러나 중요하지 않은 숫자를 제거하는 방법 (0) | 2023.11.05 |
$(이것은) AJAX 성공 내부에서 작동하지 않음 (0) | 2023.11.05 |
MariaDB Community Server 10.5 Alpha의 MariaDB Columnstore 1.4 (0) | 2023.11.05 |