Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/333.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
pConsole.StartInfo.RedirectStandardOutput和pConsole.Exit事件(c#)_C#_Console_Process - Fatal编程技术网

pConsole.StartInfo.RedirectStandardOutput和pConsole.Exit事件(c#)

pConsole.StartInfo.RedirectStandardOutput和pConsole.Exit事件(c#),c#,console,process,C#,Console,Process,我有一个GUI应用程序,它执行(在新流程中)“控制台”应用程序并解析输出。要重定向输出,我将pConsole.StartInfo.RedirectStandardOutput设置为true。我还订阅了事件pConsole.Exited 我看到的问题是,我必须在退出的事件处理程序中使用Thread.Sleep()来获取最后的数据 我退出的事件处理程序如下所示: Thread.Sleep(100); // Wait for additional data (if any). pConsole.Out

我有一个GUI应用程序,它执行(在新流程中)“控制台”应用程序并解析输出。要重定向输出,我将pConsole.StartInfo.RedirectStandardOutput设置为true。我还订阅了事件pConsole.Exited

我看到的问题是,我必须在退出的事件处理程序中使用Thread.Sleep()来获取最后的数据

我退出的事件处理程序如下所示:

Thread.Sleep(100); // Wait for additional data (if any).
pConsole.OutputDataReceived -= new System.Diagnostics.DataReceivedEventHandler(this.localTerminal_DataAvailableEvent);
int exit = pConsole.ExitCode;
pConsole.Dispose();
pConsole = null;
似乎退出的事件在我的最后一个pConsole_DataAvailableEvent之前执行。有人知道这是怎么发生的吗


我还使用互斥锁/锁来确保在开始执行下一个控制台应用程序之前退出的事件已完成。

我强烈怀疑这只是操作系统刷新任何输出缓冲区。看起来你的解决方法还行,虽然很明显这很难看(不是你的错),而且在某些情况下睡眠时间可能会浪费太长,而在某些情况下睡眠时间可能不够长。

我不知道这是否更好,但我只是在看一些类似的东西,使用线程来阅读stderr/stdout,如下所示。它涉及一些额外的线程(以避免死锁/复杂的异步代码),但似乎工作得非常稳定

这里的关键是我在处理IO的两个线程上执行了Join(),因此我只在两个输出流都被完全消耗之后才继续

            using (Process proc = Process.Start(psi))
            {
                Thread stdErr = new Thread(DumpStream(proc.StandardError, Console.Error));
                Thread stdOut = new Thread(DumpStream(proc.StandardOutput, Console.Out));
                stdErr.Name = "stderr reader";
                stdOut.Name = "stdout reader";
                stdErr.Start();
                stdOut.Start();
                proc.WaitForExit();
                stdOut.Join();
                stdErr.Join();
                if (proc.ExitCode != 0) {...} // etc
            }

    static ThreadStart DumpStream(TextReader reader, TextWriter writer)
    {
        return (ThreadStart) delegate
         {
             string line;
             while ((line = reader.ReadLine()) != null) writer.WriteLine(line);
         };
    }

问题几乎肯定是输出缓冲:进程退出,触发退出事件,但一些输出数据仍在缓冲区中。您的黑客可能在某些情况下有效,但其他方法可能更健壮。考虑:

1) 消除退出的事件处理程序,改为检查OutputDataReceived处理程序中的Process.HasExit


2) 不要使用OutputDataReceived处理程序,只需在Process.StandardOutput流上调用Read()。一旦流关闭,进行后处理清理。

除了Marc Gravell的答案之外

proc.StandardError和proc.StandardOutput都有EndOfStream方法。
这将有助于确定在用户输入/提示之前输出不产生换行符的情况

此解决方案也适用于.NET 1.1。我们中的一些人仍然需要维护遗留代码。