我正在尝试使用PowerShell解压缩大量文件。我认为这是一个很好的并行化的地方。但是,我尝试并行化似乎使解压缩没有效果,即使它在单线程模式下工作。
$unzip = {
param([string]$sourceFile, [string]$destinationDir)
#Clean out the destination if it exists
rmdir $destination -Force -Recurse -ErrorAction SilentlyContinue
mkdir $destination -Force
#Actual unzip
$shell = new-object -com shell.application
$zipFile = $shell.NameSpace($sourceFile)
$destinationDir = $shell.NameSpace($destination)
$destinationDir.copyhere($zipFile.items())
}
foreach($file in $files){
$args = ($file.FullName, $destinationDir)
Start-Job $unzip -ArgumentList $args
}
#Cleanup
While (Get-Job -State "Running") { Start-Sleep 2 }
Remove-Job *
当我在没有多线程代码的情况下运行它时,它工作正常,但有了它,实际上没有任何文件解压缩。这是为什么?
答案 0 :(得分:4)
不确定您的样本是否是复制粘贴的,但您的param是$ destinationDir,但您引用$ destination,然后使用$ destination创建$ destinationDir。我假设这是一个错字。我修复了你的功能,它可以正常运作。
$unzip = {
param([string]$sourceFile, [string]$destination)
#Clean out the destination if it exists
rmdir $destination -Force -Recurse -ErrorAction SilentlyContinue
mkdir $destination -Force
#Actual unzip
$shell = new-object -com shell.application
$zipFile = $shell.NameSpace($sourceFile)
$destinationDir = $shell.NameSpace($destination)
$destinationDir.copyhere($zipFile.items())
}
使用receive-job会向您显示以下错误,指出您正确的方向:
Cannot bind argument to parameter 'Path' because it is null.
+ CategoryInfo : InvalidData: (:) [mkdir], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,mkdir
+ PSComputerName : localhost
Method invocation failed because [System.String] doesn't contain a method named 'copyhere'.
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : MethodNotFound
+ PSComputerName : localhost
我仍然建议尽可能使用System.IO.Compression从shell.application的comobject转移到.Net解决方案。另请注意,powershell作业具有5个并发运行作业的硬盘。我不确定这是否已在v5中修复。 CookieMonster使用基于某些excellent post的运行空间编写了function和work by Boe Prox,作为处理并发性和改进性能的更好方法。