我想通過我的腳本備份一些資料。所有資料都應壓縮在一個單獨的執行緒中。但是有兩件事出錯了:
- 永遠不會呼叫函式 testFct - 指示:沒有“內部:...”。
- 缺少 ZipSource 引數 - 請參閱輸出。
呼叫腳本會導致:
> .\Backup.ps1
outside: -What: Data A -ZipSource -ZipDest C:\Users\xyz\AppData\Local\Temp -Timestamp "20220517-002854
outside: -What: Data B -ZipSource -ZipDest C:\Users\xyz\AppData\Local\Temp -Timestamp "20220517-002854
>
這是我的腳本:
class BackupContentData
{
[ValidateNotNullOrEmpty()][string]$What
[ValidateNotNullOrEmpty()][string]$ZipSource
}
$bcd = @(
[BackupContentData]@{ What="Data A"; ZipSource="$env:USERPROFILE\Documents\a_file.txt";}
[BackupContentData]@{ What="Data B"; ZipSource="$env:USERPROFILE\Documents\b_file.txt";}
)
function testFct {
param([string]$What, [string]$ZipSource, [string]$ZipDest, [string]$Timestamp)
Write-Host "inside: -What: "$What" -ZipSource "$ZipSource" -ZipDest "$ZipDest" -Timestamp "$Timestamp
}
$timestamp="$(get-date -f yyyyMMdd-HHmmss)"
foreach ($e in $bcd) {
$job = Start-ThreadJob -Name $e.What -InputObject $e -ScriptBlock {
Invoke-Expression "function getTest {$using:testFct}"
Write-Host "outside: -What: "$input.What" -ZipSource "$input.ZipSource" -ZipDest "$env:Temp" -Timestamp ""$(get-date -f yyyyMMdd-HHmmss)"
getTest -What "$input.What" -ZipSource "$input.ZipSource" -ZipDest "$env:Temp" -Timestamp "$(get-date -f yyyyMMdd-HHmmss)"
}
Receive-Job $job -AutoRemoveJob -Wait
}
腳本有什么問題?
uj5u.com熱心網友回復:
由于testFct在您的 ThreadJob 范圍內不存在,您需要首先存盤函式的定義,然后將其傳遞到運行空間范圍并在那里定義函式,如本答案所示。
另一個問題是嘗試$input多次參考相同的內容。由于自動變數$input的性質,您只能在腳本塊中參考此變數一次:
由于
$input是一個列舉器,訪問它的任何屬性都會導致$input不再可用。您可以存盤$input在另一個變數中以重用這些$input屬性。
作為一種解決方法,您可以將變數包裝在Array 子運算式運算子@( )或Subexpression 運算子$( )中,以將列舉輸出存盤在新變數中。
這是上面解釋的一個簡單示例:
Start-ThreadJob -InputObject 'Hello World' -ScriptBlock {
"1. $input"
"2. $input"
} | Receive-Job -AutoRemoveJob -Wait
# This outputs:
# 1. Hello World
# 2.
# And the workaround
Start-ThreadJob -InputObject 'Hello World' -ScriptBlock {
# This would also work:
# $thisInput = foreach($i in $input) { $i }
$thisInput = $($input)
"1. $thisInput"
"2. $thisInput"
} | Receive-Job -AutoRemoveJob -Wait
# Outputs:
# 1. Hello World
# 2. Hello World
最后,您的腳本實際上不是多執行緒的,這是因為您將作業存盤在回圈中,然后按順序等待它,而不是一次啟動所有作業,然后等待所有作業。
class BackupContentData {
[ValidateNotNullOrEmpty()] [string] $What
[ValidateNotNullOrEmpty()] [string] $ZipSource
}
function testFct {
param([string]$What, [string]$ZipSource, [string]$ZipDest, [string]$Timestamp)
Write-Host "inside: -What: $What -ZipSource $ZipSource -ZipDest $ZipDest -Timestamp $Timestamp"
}
# definition of the function is stored here
$def = ${function:testFct}.ToString()
$bcd = @(
[BackupContentData]@{ What="Data A"; ZipSource="$env:USERPROFILE\Documents\a_file.txt" }
[BackupContentData]@{ What="Data B"; ZipSource="$env:USERPROFILE\Documents\b_file.txt" }
)
$job = foreach ($e in $bcd) {
Start-ThreadJob -Name $e.What -InputObject $e -ScriptBlock {
$thisObject = $($input)
# Define a new function with name `getTest` in this scope using `testFct` definition
${function:getTest} = $using:def
Write-Host "outside: -What: $($thisObject.What) -ZipSource $($thisObject.ZipSource) -ZipDest $env:Temp -Timestamp $(get-date -f yyyyMMdd-HHmmss)"
getTest -What $thisObject.What -ZipSource $thisObject.ZipSource -ZipDest $env:Temp -Timestamp (Get-Date -f yyyyMMdd-HHmmss)
}
}
$job | Receive-Job -AutoRemoveJob -Wait
您可以期望的輸出:
outside: -What: Data A -ZipSource C:\Users\user\Documents\a_file.txt -ZipDest C:\Users\user\AppData\Local\Temp -Timestamp 20220516-202251
inside: -What: Data A -ZipSource C:\Users\user\Documents\a_file.txt -ZipDest C:\Users\user\AppData\Local\Temp -Timestamp 20220516-202251
outside: -What: Data B -ZipSource C:\Users\user\Documents\b_file.txt -ZipDest C:\Users\user\AppData\Local\Temp -Timestamp 20220516-202251
inside: -What: Data B -ZipSource C:\Users\user\Documents\b_file.txt -ZipDest C:\Users\user\AppData\Local\Temp -Timestamp 20220516-202251
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/476847.html
