Unzipping works on singlethread, but not multithread

好久不见. 提交于 2019-12-13 19:15:25

问题


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?


回答1:


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

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.



来源:https://stackoverflow.com/questions/28509659/unzipping-works-on-singlethread-but-not-multithread

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!