【问题标题】:Unzipping works on singlethread, but not multithread解压缩适用于单线程,但不适用于多线程
【发布时间】:2015-02-13 22:14:10
【问题描述】:

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

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

【问题讨论】:

  • 这可能会在SuperUser 上得到更好的答案。
  • 使用多线程不太可能显着提高性能。通常,解压缩非常快,但将解压缩的数据写入磁盘驱动器非常慢。而且由于磁盘驱动器一次只能做一件事,因此您的线程大部分时间都在等待磁盘驱动器可用。你最好只做单线程。
  • @JimMischel 是的,但我已经这样做了。我想我可能会挑战自己并让它成为多线程的,但我不知道如何让它工作。
  • 那么 $destinationDir 在您的代码中的哪个位置被分配?你在哪里调用receive-job来查看是否有错误或其他输出?那些只是不在示例中,还是完全没有?
  • $destinationDir 在示例之外被分配。它非常简单,我知道它可以工作,因为它在单线程运行时没有问题。而且我不打电话给receive-job,因为我并不真正关心输出。

标签: multithreading powershell unzip


【解决方案1】:

不确定您的示例是否复制粘贴,但您的参数是 $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

如果可能的话,我仍然建议不要使用 shell.application 的 comobject,而是使用 System.IO.Compression 的 .Net 解决方案。另请注意,powershell 作业的硬上限为 5 个同时运行的作业。我不确定这是否在 v5 中修复。 CookieMonster 使用基于一些 work by Boe Prox 的运行空间编写了 excellent postfunction,作为处理并发性的更好方法并提高了性能。

【讨论】:

    猜你喜欢
    • 2021-12-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多