呼叫控制檯應用程式3種方式效率比較
阿新 • • 發佈:2021-02-12
技術標籤: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);
}
}