解决Process因缓冲区满而导至进程阻塞的办法
2011-09-23 19:53
267 查看
首先我们看一下出现缓冲区写满的做法:
折叠C# 代码
Process p = CreateProcess("cmd",dir);//假如此处为我们从工厂中实例化一个调用cmd命令的进程
p.Start();
//从这里执行一个批处理或控制台程序,也可以是一堆CMD下的命令,我们通常会用这些来做大量的文件拷贝等操作
p.StandardInput.WriteLine("\"" + filename + "\" " + args);//写入执行参数
p.StandardInput.WriteLine("exit");//输入退出
//从此处获取所有输出信息
string result = p.StandardOutput.ReadToEnd();
p.WaitForExit();
//退出
上面的做法本身没有什么问题,但有二个缺点。
1,如果执行的程序有大量的输出信息,会导致进程阻塞,程序至此不会再跑。
2,如果我要同步获取输出信息也不可能,只能等所有的执行完成才行。
下面我们来解决这个问题:
首先定义一个工厂用来生成进程:
折叠C# 代码
/// <summary>
/// 生成进程
/// </summary>
/// <param name="filename"></param>
/// <returns></returns>
public static Process CreateProcess(string filename, string dir)
{
Process p = new Process();//进程
p.StartInfo.FileName = filename;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.UseShellExecute = false;
p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
p.StartInfo.CreateNoWindow = true;
//下面二句不可少,不然会出错
p.StartInfo.RedirectStandardInput = true;
p.StartInfo.RedirectStandardError = true;
if (!string.IsNullOrEmpty(dir))
p.StartInfo.WorkingDirectory = dir;
return p;
}
然后我们调用它生成一个进程:
折叠C# 代码
Process p = CreateProcess(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.System),"cmd.exe"), dir);
StringBuilder result = new StringBuilder();
//这里就是我们用来异步读取输出的二个委托事件
//一个是正确的信息,另一个是错误的信息输出
p.ErrorDataReceived += new DataReceivedEventHandler(delegate(object sender, DataReceivedEventArgs e)
{
//也可以是你自义定的其它处理,比如用console.write打印出来等。ShowErrorInfo(e.Data);
result.AppendLine(e.Data); //收集所有的出错信息
});
p.OutputDataReceived += new DataReceivedEventHandler(delegate(object sender, DataReceivedEventArgs e)
{
ShowNormalInfo(e.Data);
result.AppendLine(e.Data);
});
p.Start();
//这二句别忘了,不然不会触发上面的事件
p.BeginErrorReadLine();
p.BeginOutputReadLine();
//可以做你要的操作,执行批处理或其它控制台程序
//。。。。。。。。。。。
//p.StandardInput.WriteLine(input);
///////////////
p.StandardInput.WriteLine("exit");//最后打入退出命令
p.WaitForExit();
p.Close();
p.Dispose();
这样就不怕太多的输出信息阻塞进程了,希望大家有用!
折叠C# 代码
Process p = CreateProcess("cmd",dir);//假如此处为我们从工厂中实例化一个调用cmd命令的进程
p.Start();
//从这里执行一个批处理或控制台程序,也可以是一堆CMD下的命令,我们通常会用这些来做大量的文件拷贝等操作
p.StandardInput.WriteLine("\"" + filename + "\" " + args);//写入执行参数
p.StandardInput.WriteLine("exit");//输入退出
//从此处获取所有输出信息
string result = p.StandardOutput.ReadToEnd();
p.WaitForExit();
//退出
上面的做法本身没有什么问题,但有二个缺点。
1,如果执行的程序有大量的输出信息,会导致进程阻塞,程序至此不会再跑。
2,如果我要同步获取输出信息也不可能,只能等所有的执行完成才行。
下面我们来解决这个问题:
首先定义一个工厂用来生成进程:
折叠C# 代码
/// <summary>
/// 生成进程
/// </summary>
/// <param name="filename"></param>
/// <returns></returns>
public static Process CreateProcess(string filename, string dir)
{
Process p = new Process();//进程
p.StartInfo.FileName = filename;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.UseShellExecute = false;
p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
p.StartInfo.CreateNoWindow = true;
//下面二句不可少,不然会出错
p.StartInfo.RedirectStandardInput = true;
p.StartInfo.RedirectStandardError = true;
if (!string.IsNullOrEmpty(dir))
p.StartInfo.WorkingDirectory = dir;
return p;
}
然后我们调用它生成一个进程:
折叠C# 代码
Process p = CreateProcess(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.System),"cmd.exe"), dir);
StringBuilder result = new StringBuilder();
//这里就是我们用来异步读取输出的二个委托事件
//一个是正确的信息,另一个是错误的信息输出
p.ErrorDataReceived += new DataReceivedEventHandler(delegate(object sender, DataReceivedEventArgs e)
{
//也可以是你自义定的其它处理,比如用console.write打印出来等。ShowErrorInfo(e.Data);
result.AppendLine(e.Data); //收集所有的出错信息
});
p.OutputDataReceived += new DataReceivedEventHandler(delegate(object sender, DataReceivedEventArgs e)
{
ShowNormalInfo(e.Data);
result.AppendLine(e.Data);
});
p.Start();
//这二句别忘了,不然不会触发上面的事件
p.BeginErrorReadLine();
p.BeginOutputReadLine();
//可以做你要的操作,执行批处理或其它控制台程序
//。。。。。。。。。。。
//p.StandardInput.WriteLine(input);
///////////////
p.StandardInput.WriteLine("exit");//最后打入退出命令
p.WaitForExit();
p.Close();
p.Dispose();
这样就不怕太多的输出信息阻塞进程了,希望大家有用!
相关文章推荐
- SQL Server进程阻塞的检查和解决办法
- SBO进程阻塞的检查和解决办法
- 抱歉,进程android.process.media,已停止运行的解决办法
- "进程android.process.acore已意外停止" 解决办法大全
- Android手机出现android.process.media进程意外停止的解决办法(图文)
- 解决Process进程不能及时关闭及阻塞问题
- Generic Host Process进程出错问题解决办法
- SQL Server进程阻塞的检查和解决办法
- SQL Server进程阻塞的检查和解决办法
- "windows 2008 xxx 提供服务的进程 Windows Process Activation Service 通信时出现严重错误" 解决办法
- 转-"进程android.process.acore已意外停止" 解决办法
- SQL Server进程阻塞的检查和解决办法(转自好友Blog)
- jenkins 的 ProcessTreeKiller----无法启动子进程的解决办法
- SVN之下载项目一半下载中断了转圈圈无响应解决办法cleanup failed to process the following path
- "google play 已停止运行","com.google.process.gapps已停止运行"问题的解决办法
- VS编译WebService 报 进程不具有此命名空间的访问权限的解决办法
- 用存储过程查出引起死锁的进程和SQL语句--数据库死锁原因及解决办法
- HttpWebRequest使用注意(发生阻塞的解决办法)
- 安装ppstream后出现的ppsap.exe进程解决办法
- mysql中有大量sleep进程的原因与解决办法