C#启动外部进程时OutputDataReceived事件未按预期触发
问题根因
你只完成了输出重定向配置和事件绑定,但缺失了异步流读取的启动调用:OutputDataReceived、ErrorDataReceived事件不会自动监听流内容,必须显式启动异步读取逻辑,事件才会在接收到行输出时触发。
如果一直不读取重定向的流,部分输出内容较多的进程还会因为输出缓冲区写满被阻塞,最终引发进程假死。
修正方案
在process.Start()调用完成后,立刻追加两个异步读取方法的调用,启动对标准输出、标准错误流的行级监听:
process.BeginOutputReadLine(); process.BeginErrorReadLine();
修正后的完整可运行代码
using var process = new Process(); var processInfo = new ProcessStartInfo("ping.exe", "localhost"); processInfo.UseShellExecute = false; processInfo.CreateNoWindow = true; processInfo.RedirectStandardOutput = true; processInfo.RedirectStandardError = true; process.StartInfo = processInfo; process.EnableRaisingEvents = true; process.OutputDataReceived += (sender, args) => Console.WriteLine(args.Data); process.ErrorDataReceived += (sender, args) => Console.WriteLine(args.Data); process.Exited += (sender, args) => Console.WriteLine("ping finished."); process.Start(); // 关键:启动异步输出流监听,缺失则不会触发DataReceived类事件 process.BeginOutputReadLine(); process.BeginErrorReadLine(); await process.WaitForExitAsync();
额外注意事项
- 不要在使用异步行读取(
BeginOutputReadLine/BeginErrorReadLine)的同时,同步调用StandardOutput.ReadToEnd()、StandardError.ReadToEnd()等同步读取方法,两种读取逻辑混用会引发流访问冲突。 - 对接第三方命令行工具时如果发现输出延迟、不是实时触发事件,通常是因为CLI工具检测到输出目标不是控制台时,会自动切换为块缓冲模式(攒够一定大小的内容才会写入流),这种场景可以优先查找工具是否提供行缓冲启用参数(常见如
--line-buffered),同时明确配置StandardOutputEncoding、StandardErrorEncoding匹配工具的输出编码,避免乱码。
内容的提问来源于stack exchange,提问作者TJR
相关产品推荐
相关产品推荐

