【发布时间】:2013-09-02 23:48:04
【问题描述】:
我从 C# 启动一个进程,如下所示:
public bool Execute()
{
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.Arguments = "the command";
startInfo.FileName = "C:\\MyApp.exe";
startInfo.UseShellExecute = false;
startInfo.RedirectStandardOutput = true;
startInfo.RedirectStandardError = true;
Log.LogMessage("{0} {1}", startInfo.FileName, startInfo.Arguments);
using (Process myProcess = Process.Start(startInfo))
{
StringBuilder output = new StringBuilder();
myProcess.OutputDataReceived += delegate(object sender, DataReceivedEventArgs e)
{
Log.LogMessage(Thread.CurrentThread.ManagedThreadId.ToString() + e.Data);
};
myProcess.ErrorDataReceived += delegate(object sender, DataReceivedEventArgs e)
{
Log.LogError(Thread.CurrentThread.ManagedThreadId.ToString() + " " + e.Data);
};
myProcess.BeginErrorReadLine();
myProcess.BeginOutputReadLine();
myProcess.WaitForExit();
}
return false;
}
但这有一个问题......如果有问题的应用程序按此顺序写入std out和std err:
std out: msg 1
std err: msg 2
std out: msg 3
那么我从日志中看到的输出是:
msg 2
msg 1
msg 3
这似乎是因为事件处理程序是在另一个线程中执行的。所以我的问题是如何维护写入 std err 和 std out 的过程顺序?
我曾想过使用时间戳,但由于线程的抢占性,我认为这不会起作用..
更新:确认在数据上使用时间戳是没有用的。
最终更新:接受的答案解决了这个问题 - 但是它确实有一个缺点,当流合并时,无法知道写入哪个流。因此,如果您需要写入 stderr == 失败的逻辑而不是应用程序退出代码,您可能仍然会被搞砸。
【问题讨论】:
-
作为一个建议,您是否尝试过更改
BeginErrorReadLine和BeginOutputReadLine呼叫的顺序? -
查看接受的答案,这根本没有帮助
标签: c# multithreading stdout stderr