解压缩适用于单线程,但不适用于多线程

时间:2015-02-13 22:14:10

标签: multithreading powershell unzip

我正在尝试使用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 *

当我在没有多线程代码的情况下运行它时,它工作正常,但有了它,实际上没有任何文件解压缩。这是为什么?

1 个答案:

答案 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的运行空间编写了functionwork by Boe Prox,作为处理并发性和改进性能的更好方法。