线程,7-zip和Process.WaitForExit() [英] Threads, 7-zip and Process.WaitForExit()

查看:79
本文介绍了线程,7-zip和Process.WaitForExit()的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

你好,

我有一个线程池,这些线程并行执行一组任务,其中一个是通过7-zip exe完成压缩.我通过Process类生成7-zip exe;但是,当线程同时执行7-zip exe时,Process.WaitForExit()代码块 直到所有工作都完成为止(即使某些工作显然先于其他工作完成).

7-zip exe包裹在每个线程实例化的类(如下所示)周围.

我的问题是:

a)是阻止7-zip.exe的b/c,还是由于我设置线程和进程的方式?

提前谢谢!


使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用System.Text;
使用System.IO;
使用System.Diagnostics;
使用System.Text.RegularExpressions;
使用System.Data.Common;
使用System.Configuration;

命名空间Zip
{
  SevenZip类
  {
    #region私人会员

   私有字符串_sevenZipExecutablePath;
   私有字符串_compressionSwitch;

    #endregion

    #region退出代码

    ///< summary>
    ///与7-zip关联的退出代码
    ///</summary>
   枚举SevenZipExitCodeType
    {
    成功= 0,
    警告= 1,
     FatalError = 2,
     CommandLineError = 7,
     NotEnoughMemoryError = 8,
     UserStoppedProcessingError = 255
    }

    #endregion

    #region构造函数

   公共SevenZip()
    {
    }  

    #endregion

   公共无效Compress(string [] inputFileList,string outputZip)
    {
    字符串结果= string.Empty;
    字符串fileList = string.Empty;
     //迭代每个文件以确保其存在
     foreach(inputFileList中的字符串inputFile)
     {
      如果(File.Exists(inputFile))
       {
         //构造输入文件参数
         fileList + ="\" + inputFile +"\" "
       }
      其他
       {
        抛出新的ZipException(string.Format(文件不存在({0})",inputFile));
       }
     }
    
    字符串externalAppArgs = string.Format("a -t7z \" {0} \"{1} {2}",outputZip,fileList,_compressionSwitch);
     SevenZipExitCodeType exitCode =(SevenZipExitCodeType)RunCommandLine(
         _sevenZipExecutablePath
         ,externalAppArgs
         ,真实的
         ,出结果
         );

    如果(exitCode!= SevenZipExitCodeType.Success)
     {
       string error = string.Format("7-Zip Utility在压缩文件时出错.报告的错误为{0}.",
                                    Enum.GetName(typeof(SevenZipExitCodeType),exitCode));
      抛出新的ZipException(错误);
     }
    }

   私有int RunCommandLine(字符串filePath,字符串args,bool waitForExit,输出字符串结果)
    {    
     ProcessStartInfo processInfo =新的ProcessStartInfo(filePath,string.Format("{0}",args))
     {
       UseShellExecute = false,
       RedirectStandardOutput = true,
       CreateNoWindow = true,
       ErrorDialog =假,
       RedirectStandardError = true
     };

    流程=新的Process();    
     int exitCode = -1;

    试试
     {
       process.StartInfo = processInfo;
       bool resultStart = process.Start();
      如果(waitForExit)
       {
         process.WaitForExit();
         exitCode = process.ExitCode;
       }

       //使用StreamReader读取流程中的所有文本.
      使用(StreamReader reader = process.StandardOutput)
       {
        结果= reader.ReadToEnd();
       }
     }
     catch(异常异常)
     {
      抛出新的ZipException(无法为zip实用程序启动新进程.",异常);
     }

     process.Close();
     process.Dispose();

    返回exitCode;
    }
  }
}



Hello,

I have a pool of threads that perform a set of tasks in parallel, one of which is compression done via 7-zip exe. I spawn the 7-zip exe via the Process class; however, when threads execute the 7-zip exe at the same time, the Process.WaitForExit() code blocks until all have finished (even though some evidently finish before others).

The 7-zip exe is wrapped around a class (shown below) that is instantiated by each thread.

My questions is:

a) Is this blocking b/c of 7-zip.exe or due to the way I setup the threads and processes?

Thanks in advance!


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Diagnostics;
using System.Text.RegularExpressions;
using System.Data.Common;
using System.Configuration;

namespace Zip
{
  class SevenZip
  {
    #region Private Members

    private string _sevenZipExecutablePath;
    private string _compressionSwitch;

    #endregion

    #region Exit Codes

    /// <summary>
    /// Exit codes associated with 7-zip
    /// </summary>
    enum SevenZipExitCodeType
    {
      Success = 0,
      Warning = 1,
      FatalError = 2,
      CommandLineError = 7,
      NotEnoughMemoryError = 8,
      UserStoppedProcessingError = 255
    }

    #endregion

    #region Constructor

    public SevenZip()
    {
    }  

    #endregion

    public void Compress(string[] inputFileList, string outputZip)
    {
      string result = string.Empty;
      string fileList = string.Empty;
      //iterate each file to make sure it exist
      foreach (string inputFile in inputFileList)
      {
        if (File.Exists(inputFile))
        {
          //construct input file parameter
          fileList += "\"" + inputFile + "\" ";
        }
        else
        {
          throw new ZipException(string.Format("File does not exist ({0})", inputFile));
        }
      }
     
      string externalAppArgs = string.Format("a -t7z \"{0}\" {1}{2}", outputZip, fileList, _compressionSwitch);
      SevenZipExitCodeType exitCode = (SevenZipExitCodeType)RunCommandLine(
          _sevenZipExecutablePath
          , externalAppArgs
          , true
          , out result
          );

      if (exitCode != SevenZipExitCodeType.Success)
      {
        string error = string.Format("7-Zip Utility had an error zipping up files. The reported error was {0}.",
                 Enum.GetName(typeof(SevenZipExitCodeType), exitCode));
        throw new ZipException(error);
      }
    }

    private int RunCommandLine(string filePath, string args, bool waitForExit, out string result)
    {     
      ProcessStartInfo processInfo = new ProcessStartInfo(filePath, string.Format(" {0}", args))
      {
        UseShellExecute = false,
        RedirectStandardOutput = true,
        CreateNoWindow = true,
        ErrorDialog = false,
        RedirectStandardError = true            
      };

      Process process = new Process();    
      int exitCode = -1;

      try
      {
        process.StartInfo = processInfo;
        bool resultStart = process.Start();
        if (waitForExit)
        {
          process.WaitForExit();
          exitCode = process.ExitCode;
        }

        // Read in all the text from the process with the StreamReader.
        using (StreamReader reader = process.StandardOutput)
        {
          result = reader.ReadToEnd();
        }
      }
      catch (Exception exception)
      {
        throw new ZipException("Failed to start new process for zip utility.", exception);
      }

      process.Close();
      process.Dispose();

      return exitCode;
    }
  }
}



推荐答案

如果7-zip在运行时已经运行,WaitForExit是否会阻塞.开始吗?

Does WaitForExit block if 7-zip is already running when you reach process.Start?

我稍后将在具有7-zip的计算机上进行尝试,但是我猜想7-zip仅使用一个进程.当第二个7-zip进程开始时,它会检查7-zip进程是否已在运行.如果找到一个,命令将发送到已经运行的进程,然后 新的立即停止.如果您正在等待第一个进程,则将等待直到所有命令都已处理完毕.如果您正在等待第二个进程,则WaitForExit将立即返回,而无需等待命令完成.

I'll try it later on a machine with 7-zip but my guess is that 7-zip uses only one process. When a second 7-zip process starts, it checks if a 7-zip process is already running. If one is found, commands are sent to the already running process and the new one stops immediately. If you're waiting on the first process, you'll wait until all the commands have been processed. If you're waiting on the second process, WaitForExit will return immediately, without waiting for the command to be finished.


这篇关于线程,7-zip和Process.WaitForExit()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆