C# 启动进程 重定向IO 死锁避免 .
2013-02-27 11:14
225 查看
转自:http://blog.csdn.net/johnice/article/details/5577440
创建一个cmd进程,执行一个ping命令,代码如下
[c-sharp]
view plaincopyprint?
Process process = new Process();
process.StartInfo.FileName = "cmd.exe";
process.StartInfo.UseShellExecute = false; // 是否使用外壳程序
process.StartInfo.CreateNoWindow = true; // 是否在新窗口中启动该进程的值
process.StartInfo.RedirectStandardInput = true; // 重定向输入流
//process.StartInfo.RedirectStandardOutput = true; // 重定向输出流
//process.StartInfo.RedirectStandardError = true; // 重定向错误流
string strCmd = "ping www.163.com /r/n";
strCmd += "exit";
process.Start();
process.StandardInput.WriteLine(strCmd);
//string output = process.StandardOutput.ReadToEnd(); // 获取输出信息
process.WaitForExit();
int n = process.ExitCode; // n 为进程执行返回值
process.Close();
Process process = new Process();
process.StartInfo.FileName = "cmd.exe";
process.StartInfo.UseShellExecute = false; // 是否使用外壳程序
process.StartInfo.CreateNoWindow = true; // 是否在新窗口中启动该进程的值
process.StartInfo.RedirectStandardInput = true; // 重定向输入流
//process.StartInfo.RedirectStandardOutput = true; // 重定向输出流
//process.StartInfo.RedirectStandardError = true; // 重定向错误流
string strCmd = "ping www.163.com /r/n";
strCmd += "exit";
process.Start();
process.StandardInput.WriteLine(strCmd);
//string output = process.StandardOutput.ReadToEnd(); // 获取输出信息
process.WaitForExit();
int n = process.ExitCode; // n 为进程执行返回值
process.Close();
这里使用了 process.WaitForExit(), 会等到process进程执行结束,并获得输出
StartInfo的三个属性:RedirectStandardInput、RedirectStandardOutput、RedirectStandardError,分别重定向了进程的输入、输出、错误,三个流,对于output和error信息,如果没有需要可以不重定向,因为对他们的读取容易造成死锁
对进程output流和error流的读取有2种方式:同步 or 异步
同步:
如例子中代码,在WaitForExit之前调用string output = process.StandardOutput.ReadToEnd();(或者StandardError)进行读取,只能等进程结束后才能获取输出信息,且容易由于stream被填满而发生死锁(详情见下面的msdn链接)
异步:
使用事件和委托,进程有2个事件OutputDataReceived、OutputDataReceived
我们可以注册这2个事件,使该进程在往Output和error流中填充数据时,调用相应的事件响应函数,及时处理流中数据,从而避免流被填满而发生的死锁情况,在WaitForExit之前调用BeginOutputReadLine 或者BeginErrorReadLine 开始异步读取
顺便记下事件的简单写法:
process.OutputDataReceived += (s, e) => Console.WriteLine(e.Data);
真简洁啊 学习学习 不禁感慨 不懂的东西实在太多了 摇头轻叹ing
参考MSDN:http://msdn.microsoft.com/zh-cn/library/system.diagnostics.process.standardoutput(VS.80).aspx
另:c#中开启进程还有种方法,
System.Diagnostics.Process.Start(@"C:/listfiles.bat");
这种方式不等待子进程退出,相当于异步(不知道这么说对不 - -)
创建一个cmd进程,执行一个ping命令,代码如下
[c-sharp]
view plaincopyprint?
Process process = new Process();
process.StartInfo.FileName = "cmd.exe";
process.StartInfo.UseShellExecute = false; // 是否使用外壳程序
process.StartInfo.CreateNoWindow = true; // 是否在新窗口中启动该进程的值
process.StartInfo.RedirectStandardInput = true; // 重定向输入流
//process.StartInfo.RedirectStandardOutput = true; // 重定向输出流
//process.StartInfo.RedirectStandardError = true; // 重定向错误流
string strCmd = "ping www.163.com /r/n";
strCmd += "exit";
process.Start();
process.StandardInput.WriteLine(strCmd);
//string output = process.StandardOutput.ReadToEnd(); // 获取输出信息
process.WaitForExit();
int n = process.ExitCode; // n 为进程执行返回值
process.Close();
Process process = new Process();
process.StartInfo.FileName = "cmd.exe";
process.StartInfo.UseShellExecute = false; // 是否使用外壳程序
process.StartInfo.CreateNoWindow = true; // 是否在新窗口中启动该进程的值
process.StartInfo.RedirectStandardInput = true; // 重定向输入流
//process.StartInfo.RedirectStandardOutput = true; // 重定向输出流
//process.StartInfo.RedirectStandardError = true; // 重定向错误流
string strCmd = "ping www.163.com /r/n";
strCmd += "exit";
process.Start();
process.StandardInput.WriteLine(strCmd);
//string output = process.StandardOutput.ReadToEnd(); // 获取输出信息
process.WaitForExit();
int n = process.ExitCode; // n 为进程执行返回值
process.Close();
这里使用了 process.WaitForExit(), 会等到process进程执行结束,并获得输出
StartInfo的三个属性:RedirectStandardInput、RedirectStandardOutput、RedirectStandardError,分别重定向了进程的输入、输出、错误,三个流,对于output和error信息,如果没有需要可以不重定向,因为对他们的读取容易造成死锁
对进程output流和error流的读取有2种方式:同步 or 异步
同步:
如例子中代码,在WaitForExit之前调用string output = process.StandardOutput.ReadToEnd();(或者StandardError)进行读取,只能等进程结束后才能获取输出信息,且容易由于stream被填满而发生死锁(详情见下面的msdn链接)
异步:
使用事件和委托,进程有2个事件OutputDataReceived、OutputDataReceived
我们可以注册这2个事件,使该进程在往Output和error流中填充数据时,调用相应的事件响应函数,及时处理流中数据,从而避免流被填满而发生的死锁情况,在WaitForExit之前调用BeginOutputReadLine 或者BeginErrorReadLine 开始异步读取
顺便记下事件的简单写法:
process.OutputDataReceived += (s, e) => Console.WriteLine(e.Data);
真简洁啊 学习学习 不禁感慨 不懂的东西实在太多了 摇头轻叹ing
参考MSDN:http://msdn.microsoft.com/zh-cn/library/system.diagnostics.process.standardoutput(VS.80).aspx
另:c#中开启进程还有种方法,
System.Diagnostics.Process.Start(@"C:/listfiles.bat");
这种方式不等待子进程退出,相当于异步(不知道这么说对不 - -)
相关文章推荐
- C# 启动进程 重定向IO 死锁避免
- C# System.IO.FileStream 文件正由另一进程使用,因此该进程无法访问该文件
- 小议避免进程退出时的死锁
- c#的Process启动另一个进程作为程序的一个界面
- C# System.IO.FileStream 读取被其他程序打开的文件提示“文件正由另一进程使用,因此该进程无法访问该文件。”
- C# 实现shellcode 进程启动注入eip注入
- c# 启动关闭进程
- C#程序多用户只启动一个进程的方法[转载]
- C#避免程序二次启动并接收参数
- SQL Server中解决死锁的新方法介绍和C#中多线程避免并发
- C# System.IO.FileStream 文件正由另一进程使用,因此该进程无法访问该文件
- C#进程启动实例
- C#程序多用户只启动一个进程的方法[转载]
- C# 中启动进程的三种方法
- 简单掌握Windows中C#启动外部程序进程的方法
- C# 最基本的涉及模式(单例模式) C#种死锁:事务(进程 ID 112)与另一个进程被死锁在 锁 | 通信缓冲区 资源上,并且已被选作死锁牺牲品。请重新运行该事务,解决方案: C#关闭应用程序时如何关闭子线程 C#中 ThreadStart和ParameterizedThreadStart区别
- C# 进程启动与关闭
- c++ 模拟银行家调度算法 避免进程死锁
- C#实现启动,关闭与查找进程的方法
- C#启动和关闭进程操作