这是一种非常令人惊讶的结果的“犯罪研究” - 至少对我而言。
我们正在使用Process对象运行外部命令。我们正在异步地捕获标准输出(和标准错误 - 我已经从样本中删除了这个以清除原因)。这里已经多次回答了这个问题。代码看起来像这样,工作正常:
var process = new Process
{
StartInfo =
{
UseShellExecute = false,
RedirectStandardOutput = true,
FileName = @"...\TestApp.exe"
}
};
process.OutputDataReceived += Process_OutputDataReceived;
process.Start();
process.BeginOutputReadLine();
process.WaitForExit();
process.OutputDataReceived -= Process_OutputDataReceived;
现在,如果我想向WaitForExit()
添加硬超时怎么办?简单:WaitForExit(int milliseconds)
的重载版本。所以像这样的电话应该这样做:
process.WaitForExit(60000);
现在,这会导致输出捕获在某些情况下不完整。
这不是秘密,至少不是微软的开发人员。经过几个小时的研究,我得出的结论是WaitForExit的实现一定有问题。所以我看了一下代码,我在微软的实现中发现了这个评论:
// If we have a hard timeout, we cannot wait for the streams
这是我的问题 - 我做了很多评估而没有成功:
如何在WaitForExit()
上进行硬超时,同时确保控制台输出捕获已完成?
答案 0 :(得分:1)
您是否尝试在派生类中使用OnExited事件? See this。这可能允许您使用超时等待而不是将其传递给WaitForExit。
答案 1 :(得分:0)
@Hans Passant你的评论指引我走向正确的方向。实际上,我真的不知道Sleep()
有多长。但我可以为此添加一个简单的看门狗。由于当我必须开始等待丢失的捕获时,该过程已经完成,我可以假设OutputDataReceived
事件被持续触发,直到流为空。所以我所做的就是添加一个Stopwatch
并在每次OutputDataReceived
事件方法的开头重新启动它。在主代码中,我用以下代码替换了对WaitForExit(60000)
的调用:
if (process.WaitForExit(60000))
{
while (outputWatch.ElapsedMilliseconds < 20) Thread.Sleep(20);
}
好的,此代码中还有一个Thread.Sleep()
。但它绝对算上0.05%...... :)。