C# 异步使用System.Diagnostics.Process,如何确保;在确定是否已退出之前,您是否已收到最后一次输出?

C# 异步使用System.Diagnostics.Process,如何确保;在确定是否已退出之前,您是否已收到最后一次输出?,c#,.net,asynchronous,process,C#,.net,Asynchronous,Process,考虑以下示例C#代码(忽略不相关的部分): 现在,我想通知一个监听器,在没有更多的输出(stdout/stderr)可从中读取后,该进程就完成了。如何确保在我的ExitHandler方法中,所有剩余的stdout/stderr都由outpurthandler和ErrorHandler处理,然后再确定进程已真正完成?当进程中止或终止时,将调用该事件。因此,决不应出现仍有数据需要读取的情况 当操作系统关闭进程时,任何进程组件 正在等待退出的用户将收到通知。然后,该组件可以访问 仍驻留在中的关联流程信

考虑以下示例C#代码(忽略不相关的部分):

现在,我想通知一个监听器,在没有更多的输出(stdout/stderr)可从中读取后,该进程就完成了。如何确保在我的
ExitHandler
方法中,所有剩余的stdout/stderr都由
outpurthandler
ErrorHandler
处理,然后再确定进程已真正完成?

当进程中止或终止时,将调用该事件。因此,决不应出现仍有数据需要读取的情况

当操作系统关闭进程时,任何进程组件 正在等待退出的用户将收到通知。然后,该组件可以访问 仍驻留在中的关联流程信息 通过使用 处理它对流程的影响

由于关联的进程已退出,因此 组件不再指向现有流程资源。相反 它只能用于访问操作系统有关的信息 进程资源。系统知道要退出的句柄 流程组件尚未发布的流程,因此 将ExitTime和Handle属性信息保留在内存中,直到 流程组件专门释放资源


显式使用Process.WaitForExit(-1)时会出现互锁。在stdout和stderr的异步读取器指示文件结束状态之前,它不会返回。在退出的事件处理程序中调用它。您必须使用-1的超时,否则将无法工作。或者只是等待Forexit()。很好,你知道它已经退出了。

我应该在我的
ExitHandler
方法中调用
WaitForExit
?嗯。。。我想我曾经体验过,在调用
ExitHandler
之后,在另一个线程中使用非空数据调用了
outputhHandler
。可能是因为另一个进程(我启动了两个进程),我不太确定了…这个答案不正确,操作系统不能保证线程被及时调用。我想你是对的,可能是进程退出后延迟到达的事件。但在这种情况下,它所持有的数据是有效的,因为它是在退出之前发送的,并且仍然应该被处理。我的观点是,退出后,不能再触发任何流事件。好吧,对我来说,是否有更多的数据要从进程中读取并不重要,但是否有更多的数据要处理。我的问题中也明确规定了这一点。因此,这是一种已知的模式,用于确保stdout/stderr处理已在退出的
处理程序中完成?我看到
WaitForExit()的文档
说明:此方法指示流程组件等待无限长的时间,等待流程和事件处理程序退出。这听起来像是我需要的。我认为在所有其他事件处理完成后,
退出的
处理程序中没有任何保证。我将此标记为解决方案,因为从参考文档中可以看出它是正确的。不过,我认为负超时是不必要的,因为根据引用,它应该对应于
WaitForExit()
重载。我不确定我是否明白你的意思?你的回答肯定很有帮助,我只是觉得从文档判断,-1是不必要的。这与等待
WaitForExit()
是我最初的回答一样。我改变了它,因为它没有解决这个问题。这只是等待退出事件的同步版本。
using System.Diagnostics.Process;

var process = new Process();
var startInfo = process.StartInfo;
startInfo.RedirectStandardOutput = true;
startInfo.RedirectStandardError = true;
process.EnableRaisingEvents = true;
process.OutputDataReceived += OutputHandler;
process.ErrorDataReceived += ErrorHandler;
process.Exited += ExitHandler;
process.Start();
process.BeginOutputReadLine();
process.BeginErrorReadLine();