1. 程式人生 > 其它 >呼叫控制檯應用程式3種方式效率比較

呼叫控制檯應用程式3種方式效率比較

技術標籤:C#

基於C#語言,呼叫cmd控制檯,執行其他exe程式效率比較,分為3種方式:

  • 後臺靜默同步執行exe程式
  • 後臺靜默非同步執行exe程式
  • 後臺顯示cmd視窗執行
    寫了一個輸出1-100數字的控制檯exe程式,輸出完之後,系統等待20秒,總耗時應該20秒多一點,比較效率的程式碼為:
  Stopwatch watch = new Stopwatch();

  watch.Start();
   string exePath = "D:\\VSApplication\\ExeTestCSharp\\ExeTestCSharp\\bin\\Release\\ExeTestCSharp.exe"
; string result = QConsoleTest.QCmdShell.ExecuteCmdShell(exePath, "-GUID", "QCJ"); watch.Stop(); Console.WriteLine("同步:" + watch.Elapsed.TotalSeconds); Console.WriteLine(result); watch.Restart(); string sb = QConsoleTest.QCmdShell.ExecuteCmdShellAsync(exePath,
"-GUID", "2"); watch.Stop(); Console.WriteLine("非同步:" + watch.Elapsed.TotalSeconds); Console.WriteLine(sb); watch.Restart(); string res = QConsoleTest.QCmdShell.ExecuteCmdShellHasWindow(exePath,true, "-GUID", "3"); watch.Stop(); Console.
WriteLine("顯示視窗:" + watch.Elapsed.TotalSeconds); Console.WriteLine(res);

輸出結果:
在這裡插入圖片描述
可見,非同步呼叫最快,顯示視窗最慢,後臺靜默呼叫可以獲取控制檯exe程式本身控制檯輸出的結果或者錯誤資訊,而顯示視窗方式會直接開啟ExeTestCSharp.exe的控制檯視窗,測試的控制檯ConsoleTest並不能獲取被呼叫的控制檯上輸出的資訊。

非同步呼叫時,可以在OutputDataReceived事件中與主程式控制元件聯動。

所以推薦使用非同步呼叫視窗,原始碼為:


 private static StringBuilder sData = new StringBuilder();
 
/// <summary>
 /// 非同步執行命令列程式
 /// </summary>
 /// <param name="cmdShellPath"></param>
 /// <param name="inputArguments"></param>
 /// <returns></returns>
 public static string ExecuteCmdShellAsync(string cmdShellPath, params string[] inputArguments)
 {
     sData.Clear();
     string shellMsg = "";
     string argus = inputArguments.Where(arg => string.IsNullOrEmpty(arg) == false).Aggregate("", (current, arg) => current + arg + " ");
     argus = argus.Trim();
     //建立程序物件
     Process process = new Process();
     //引數
     ProcessStartInfo startInfo = new ProcessStartInfo
     {
         FileName = cmdShellPath,      
         Arguments = argus,            
         CreateNoWindow = true,        
         UseShellExecute = false,      
         RedirectStandardInput = false,
         RedirectStandardOutput = true,  //將輸出資訊重定向,而不是預設的顯示在dos控制檯上
     };
     process.StartInfo = startInfo;
     //新增事件
     process.OutputDataReceived += OutputDataReceivedHandler;
     try
     {
         if (!process.Start())
         {
             sData.Append("錯誤:程式未執行");
             return sData.ToString();
         }
         process.BeginOutputReadLine();
         process.BeginErrorReadLine();
          // 使當前執行緒等待,直到關聯程序終止
         process.WaitForExit();         
     }
     catch (Exception exception)
     {
         shellMsg = "錯誤:" + exception.Message;
     }
     finally
     {
         process.Close();
         process.Dispose();
         process = null;
     }

     return sData.ToString().TrimEnd();
 }
 
//非同步資料接受響應事件
 private static void OutputDataReceivedHandler(object sender, DataReceivedEventArgs e)
 {
     try
     {
         if (!string.IsNullOrEmpty(e.Data))
         {
             sData.Append(e.Data + Environment.NewLine);
         }
     }
     catch (Exception ex)
     {
         sData.Append(ex.Message + Environment.NewLine);
     }
 }