• c# 调用cmd 输出 阻塞 解决


    引用:http://www.jiamaocode.com/Cts/1031.html

    异步输出

    折叠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();  
  • 相关阅读:
    2017-2018 ACM-ICPC, Asia Tsukuba Regional Contest E:Black or White
    树状数组--二叉索引树
    P1654 OSU!-洛谷luogu
    P1365 WJMZBMR打osu! / Easy-洛谷luogu
    P4550 收集邮票-洛谷luogu
    P2257 YY的GCD--洛谷luogu

    P3200 [HNOI2009]有趣的数列--洛谷luogu
    catalan数
    lucas定理
  • 原文地址:https://www.cnblogs.com/sode/p/2583941.html
Copyright © 2020-2023  润新知