即使EnableRaisingEvents设置为true,也永远不会调用Process.Exited
我有一个可执行文件,当我手动运行时运行正常,并且它应该与预期输出一样存在。 但是当我使用下面的方法运行它时,Process.Exited事件永远不会被触发。 请注意,我记得Process.EnableRaisingEvents
protected override Result Execute(RunExecutable task) { var process = new Process(); process.StartInfo.Arguments = task.Arguments; process.StartInfo.FileName = task.ExecutablePath; process.StartInfo.CreateNoWindow = true; process.StartInfo.UseShellExecute = false; process.StartInfo.RedirectStandardOutput = true; process.EnableRaisingEvents = true; process.Exited += (sender, args) => { processSync.OnNext(new Result { Success = process.ExitCode == 0, Message = process.StandardOutput.ReadToEnd() }); processSync.OnCompleted(); }; process.Start(); return processSync.First();; }
问题是一样的,如果我使用Process.WaitForExit()而不是反应式扩展,等待退出事件。
此外,如果我使用另一个参数运行该进程,这会生成另一个输出,它就可以了。
它似乎与process.StartInfo.RedirectStandardOutput = true;
因为当我禁用它时,它的工作原理。 但这可能只是另一个问题的症状。
任何帮助表示赞赏:-)
您的代码中存在死锁。 “标准输出”只是一种命名管道,它有一个小缓冲区,用于将数据从一个进程传输到另一个进程。 如果缓冲区已满,则写入过程必须等待读取过程从缓冲区中检索一些数据。
所以你已经开始的过程可能会等待你从标准输出中读取,但是在开始阅读之前你正在等待进程完成 – >死锁。
解决方案是在进程运行时连续读取 – 只需在调用WaitForExit()
之前调用StandardOutput.ReadToEnd()
WaitForExit()
。 如果要在不阻塞当前线程的情况下进行读取,可以使用BeginOutputReadLine()
和OutputDataReceived
事件。
显然,如果重定向它,则必须侦听StandardOutput流,否则Process将不会退出。 它等待某人先读取输出。
不调用Process.Exited事件