我使用C#写个小工具,里面调用Process类启动了一个新的进程并通过回调函数分析进程的输出信息,代码示例如下:
private Process? adbProcess = null;
public void test()
{
if (adbProcess is not null)
{
return;
}
adbProcess = new Process
{
EnableRaisingEvents = true,
StartInfo = psi
};
adbProcess.Exited += new EventHandler(WriteSNProcessExited);
adbProcess.OutputDataReceived += WriteCommandOutuptHandler;
adbProcess.ErrorDataReceived += WriteCommandOutuptHandler;
adbProcess.Start();
adbProcess.BeginOutputReadLine();
adbProcess.BeginErrorReadLine();
}
private void WriteCommandOutuptHandler(object sender, DataReceivedEventArgs e)
{
if (e.Data is null)
{
return;
}
// 我想在这里处理一些输出数据
// 但是我如何知道我当前处理的这一段数据就是进程给出的最后一段数据呢?
// 通过 adbProcess?.HasExited 来判断吗?
}
请问:
问题是,进程可能已经结束了,但是它运行时输出的数据我可能还没处理完毕呢,那我在处理数据的时候,如何正确判断这一次处理的数据就是最后一段数据了呢?
是通过adbProcess?.HasExited
来判断吗?
进程的输出处理与进程实际的执行环境属于不同的上下文环境,那adbProcess?.HasExited
返回为真值的时候,似乎不能代表adbProcess.OutputDataReceived
就是最后一次执行吧?
你的理解是正确的。adbProcess?.HasExited 只表示进程是否已经退出,但不能确保 adbProcess.OutputDataReceived 事件的触发是最后一次执行。进程的输出和进程的退出是不同的上下文,它们在不同的线程中执行。
为了确定处理的数据是否是最后一段数据,你可以考虑使用一个标志来追踪是否已经收到了最后一段数据,并在处理完最后一段数据后进行特殊处理。以下是一个示例:
csharp
private bool isLastDataReceived = false;
private void WriteCommandOutuptHandler(object sender, DataReceivedEventArgs e)
{
if (e.Data is null)
{
// 数据已处理完毕,可以进行额外操作
if (isLastDataReceived)
{
// 在这里处理最后一次数据的逻辑
// 例如,关闭资源或触发其他操作
}
return;
}
// 处理输出数据
// ...
// 如果需要判断是否是最后一段数据,可以设置标志
if (someCondition) // 根据实际情况设置标志
{
isLastDataReceived = true;
}
}
在上面的示例中,当你确定已经接收到最后一段数据时,设置 isLastDataReceived 标志为 true。在事件处理程序中检查此标志,如果标志为 true 并且数据为 null,则表示最后一段数据已经处理完毕,你可以在这里执行任何必要的最后一次处理操作。
注意,需要根据实际情况设置 isLastDataReceived 的条件,以确保在接收到最后一段数据时将其设置为 true。这可能涉及到检查输出数据的某些特定条件或通过其他方式来确定。
感谢答复。
我对你的回复做如下理解:
就是在output的回调函数中通过检查输出信息的特定关键信息来作为结束的条件。
是这样吗?
我觉得你建议的这个操作一般都是可行的,但这其实并不是我真正想要的结果。
比如说我执行 adb devices
这么一条命令,那么adb会输出已经连接上的所有的设备,可它最后并不会给出一条比如说“All devices are listed.”
这样的关键信息来表示它的所有输出已经完成了。
我真正期望地是这个处理输出数据的管道进程能够明确的给我一个回调或者信号通知我说一切都已经结束了,实际上我没找到这样的接口。
我目前的做法是在新开辟进程的exit回调函数中,新启动一个Timer,延期一段时间之后来通知output处理进程结束处理。
这个方法很笨,也不够及时,但是我目前也只能想到这个一个笨招了。