from:https://msdn.microsoft.com/zh-cn/library/system.diagnostics.process.beginoutputreadline(v=vs.80).aspx?cs-save-lang=1&cs-lang=csharp#code-snippet-4
可同步或异步读取 StandardOutput 流。Read、ReadLine 和 ReadToEnd 等方法对进程的输出流执行同步读取操作。这些同步读取操作只有在关联的 Process 写入其 StandardOutput 流或关闭该流后才能完成。
相反,BeginOutputReadLine 在 StandardOutput 流上开始异步读取操作。此方法会为流输出启用一个指定的事件处理程序并立即返回到调用方,这样当流输出被定向到该事件处理程序时,调用方还可以执行其他操作。
按照这些步骤对 Process 的 StandardOutput 执行异步读取操作:
将 UseShellExecute 设置为 false。
将 RedirectStandardOutput 设置为 true。
向 OutputDataReceived 事件添加事件处理程序。事件处理程序必须与 System.Diagnostics.DataReceivedEventHandler 委托签名相匹配。
启动 Process。
调用 Process 的 BeginOutputReadLine。此调用将启动 StandardOutput 上的异步读取操作。
启动异步读取操作时,关联的 Process 每向其 StandardOutput 流写入一行文本时,都将调用该事件处理程序。
可通过调用 CancelOutputRead 取消异步读取操作。可通过调用方或事件处理程序取消读取操作。取消之后,可以再次调用BeginOutputReadLine 继续进行异步读取操作。
注意 |
---|
您不能对同一个重定向流混合使用异步和同步读取操作。在异步或同步模式下打开 Process 的重定向流后,对该流的所有进一步的读取操作都必须在同一模式下进行。例如,不要对 StandardOutput 流调用 BeginOutputReadLine 后接着调用 ReadLine,反之亦然。但是,您可以在不同的模式下读取两个不同的流。例如,您可以先调用 BeginOutputReadLine,然后再为 StandardError 流调用 ReadLine。 |
下面的示例说明如何在 sort 命令的重定向 StandardOutput 流上执行异步读取操作。sort 命令是读取文字输入并对其进行排序的一种控制台应用程序。
本示例将为 SortOutputHandler 事件处理程序创建事件委托,并使其与 OutputDataReceived 事件相关联。事件处理程序收到来自重定向StandardOutput 流的文本行,然后设置该文本的格式并将文本写到屏幕上。
// Define the namespaces used by this sample. using System; using System.Text; using System.IO; using System.Diagnostics; using System.Threading; using System.ComponentModel;namespace ProcessAsyncStreamSamples {class SortOutputRedirection{// Define static variables shared by class methods.private static StringBuilder sortOutput = null;private static int numOutputLines = 0;public static void SortInputListText(){// Initialize the process and its StartInfo properties.// The sort command is a console application that// reads and sorts text input.Process sortProcess;sortProcess = new Process();sortProcess.StartInfo.FileName = "Sort.exe";//捕获Sort.exe的cout输出// Set UseShellExecute to false for redirection.sortProcess.StartInfo.UseShellExecute = false;// Redirect the standard output of the sort command. // This stream is read asynchronously using an event handler.sortProcess.StartInfo.RedirectStandardOutput = true;sortOutput = new StringBuilder("");// Set our event handler to asynchronously read the sort output.sortProcess.OutputDataReceived += new DataReceivedEventHandler(SortOutputHandler);// Redirect standard input as well. This stream// is used synchronously.sortProcess.StartInfo.RedirectStandardInput = true;// Start the process.sortProcess.Start();// Use a stream writer to synchronously write the sort input.StreamWriter sortStreamWriter = sortProcess.StandardInput;// Start the asynchronous read of the sort output stream.sortProcess.BeginOutputReadLine();// Prompt the user for input text lines. Write each // line to the redirected input stream of the sort command.Console.WriteLine("Ready to sort up to 50 lines of text");String inputText;int numInputLines = 0;do {Console.WriteLine("Enter a text line (or press the Enter key to stop):");inputText = Console.ReadLine();if (!String.IsNullOrEmpty(inputText)){numInputLines ++;sortStreamWriter.WriteLine(inputText);}}while (!String.IsNullOrEmpty(inputText) && (numInputLines < 50));Console.WriteLine("<end of input stream>");Console.WriteLine();// End the input stream to the sort command.sortStreamWriter.Close();// Wait for the sort process to write the sorted text lines.sortProcess.WaitForExit();if (numOutputLines > 0){// Write the formatted and sorted output to the console.Console.WriteLine(" Sort results = {0} sorted text line(s) ", numOutputLines);Console.WriteLine("----------");Console.WriteLine(sortOutput);}else {Console.WriteLine(" No input lines were sorted.");}sortProcess.Close();}private static void SortOutputHandler(object sendingProcess, DataReceivedEventArgs outLine){// Collect the sort command output.if (!String.IsNullOrEmpty(outLine.Data)){numOutputLines++;// Add the text to the collected output.sortOutput.Append(Environment.NewLine + "[" + numOutputLines.ToString() + "] - " + outLine.Data);}}} }