zoukankan      html  css  js  c++  java
  • 解决Process因缓冲区满而导至进程阻塞的办法

    首先我们看一下出现缓冲区写满的做法:

    折叠C# 代码
    1. Process p = CreateProcess("cmd",dir);//假如此处为我们从工厂中实例化一个调用cmd命令的进程   
    2. p.Start();   
    3. //从这里执行一个批处理或控制台程序,也可以是一堆CMD下的命令,我们通常会用这些来做大量的文件拷贝等操作   
    4. p.StandardInput.WriteLine("\"" + filename + "\" " + args);//写入执行参数   
    5. p.StandardInput.WriteLine("exit");//输入退出   
    6. //从此处获取所有输出信息   
    7. string result = p.StandardOutput.ReadToEnd();   
    8. p.WaitForExit();   
    9. //退出  

    上面的做法本身没有什么问题,但有二个缺点。

    1,如果执行的程序有大量的输出信息,会导致进程阻塞,程序至此不会再跑。

    2,如果我要同步获取输出信息也不可能,只能等所有的执行完成才行。

     

    下面我们来解决这个问题:

    首先定义一个工厂用来生成进程:

    折叠C# 代码
    1.         /// <summary>   
    2.         /// 生成进程   
    3.         /// </summary>   
    4.         /// <param name="filename"></param>   
    5.         /// <returns></returns>   
    6.         public static Process CreateProcess(string filename, string dir)   
    7.         {   
    8.   
    9.             Process p = new Process();//进程   
    10.             p.StartInfo.FileName = filename;   
    11.             p.StartInfo.RedirectStandardOutput = true;   
    12.             p.StartInfo.UseShellExecute = false;   
    13.             p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;   
    14.             p.StartInfo.CreateNoWindow = true;   
    15.            //下面二句不可少,不然会出错   
    16.             p.StartInfo.RedirectStandardInput = true;               
    17.             p.StartInfo.RedirectStandardError = true;   
    18.             if (!string.IsNullOrEmpty(dir))   
    19.                 p.StartInfo.WorkingDirectory = dir;   
    20.   
    21.             return p;   
    22.   
    23.         }   

    然后我们调用它生成一个进程:

    折叠C# 代码
    1. Process p = CreateProcess(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.System),"cmd.exe"), dir);   
    2.                 StringBuilder result = new StringBuilder();   
    3.   
    4. //这里就是我们用来异步读取输出的二个委托事件   
    5. //一个是正确的信息,另一个是错误的信息输出   
    6. p.ErrorDataReceived += new DataReceivedEventHandler(delegate(object sender, DataReceivedEventArgs e)   
    7.                 {   
    8.                     //也可以是你自义定的其它处理,比如用console.write打印出来等。ShowErrorInfo(e.Data);   
    9.                     result.AppendLine(e.Data);   //收集所有的出错信息                    
    10.                 });   
    11.                 p.OutputDataReceived += new DataReceivedEventHandler(delegate(object sender, DataReceivedEventArgs e)   
    12.                 {   
    13.                     ShowNormalInfo(e.Data);   
    14.                     result.AppendLine(e.Data);                      
    15.                 });   
    16. p.Start();   
    17.   
    18. //这二句别忘了,不然不会触发上面的事件   
    19. p.BeginErrorReadLine();   
    20. p.BeginOutputReadLine();   
    21.   
    22. //可以做你要的操作,执行批处理或其它控制台程序   
    23. //。。。。。。。。。。。   
    24.   
    25. //p.StandardInput.WriteLine(input);   
    26. ///////////////   
    27.   
    28. p.StandardInput.WriteLine("exit");//最后打入退出命令   
    29.   
    30. p.WaitForExit();   
    31. p.Close();   
    32. p.Dispose();  

    这样就不怕太多的输出信息阻塞进程了,希望大家有用!

    Powered By D&J (URL:http://www.cnblogs.com/Areas/)
  • 相关阅读:
    获取到某一方法的调用者的类名、方法名、命名空间(转)
    JQ插件收集
    输出KnownColor枚举颜色值
    SQL 优化之该走索引却不走索引的分析
    oracle日期处理(一)
    ORACLE如何使用DBMS_METADATA.GET_DDL获取DDL语句
    案例分析:ora04031与ora04030错误分析与解决
    分区表、分区索引和全局索引部分总结
    Oracle性能调整指导纲要
    ORACLE常用SQL优化hint语句
  • 原文地址:https://www.cnblogs.com/Areas/p/2186597.html
Copyright © 2011-2022 走看看