解压缩适用于单线程,但不适用于多线程 [英] Unzipping works on singlethread, but not multithread
问题描述
我正在尝试使用PowerShell解压缩大量文件.我认为这是并行化的好地方.但是,即使它在单线程模式下工作,我进行并行化的尝试似乎也无法使它解压缩.
I'm trying to unzip a ton of files using PowerShell. I figured this is a great place to parallelize. However, my attempt to parallelize seems to make the unzip have no effect, even though it worked in the single threaded mode.
$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 *
当我在没有多线程代码的情况下运行此程序时,它可以正常工作,但实际上没有文件解压缩.为什么会这样?
When I run this without the multithreaded code, it works fine, but with it none of the files actually get unzipped. Why is this?
推荐答案
不确定示例是否复制粘贴,但参数为$ destinationDir,但您引用$ destination,然后使用$ destination创建$ destinationDir.我假设这是一个错字.我修复了您的功能,它可以按预期工作.
Not sure if your sample is copy pasted or not, but your param is $destinationDir but you reference $destination and then use $destination to create $destinationDir. I'm assuming this is a typo. I fixed your function and it works as you would expect.
$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())
}
使用接收工作会向您显示以下错误,指示您朝着正确的方向:
Using receive-job would have shown you the following errors pointing you in the right direction:
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
如果可能的话,我仍然建议从shell.application的comobject转移到使用System.IO.Compression的.Net解决方案.还要注意,PowerShell作业的硬上限为5个同时运行的作业.我不确定这在v5中是否已解决. CookieMonster撰写了优秀文章和功能使用基于某些
I would still recommend moving away from the comobject for shell.application and to a .Net solution using System.IO.Compression if possible however. Also note that powershell jobs have a hard cap of 5 concurrently running jobs. I'm not sure if this is fixed in v5 or not. CookieMonster wrote an excellent post and a function using runspaces based off some work by Boe Prox as a better way of handling concurrency with improved performance.
这篇关于解压缩适用于单线程,但不适用于多线程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!