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);}}} }