實時進度條 - Spectre Console系列
Spectre.Console程式庫旨在將普通C#控制台應用程式轉化為視覺吸引且具資訊性的工具。 其最引人注目的特點之一就是可以顯示應用程式運行過程中更新的進度條。 這對於需要讓使用者了解的長時間運行任務特別有用。
在他的"Live Progress Bars – Spectre Console Series"影片中,Tim Corey逐步展示如何創建C# Spectre Console進度條。
設置控制台應用程式
在影片的開頭(0:00),Tim介紹了Spectre.Console控制台程式庫,並顯示了影片下方有來源程式碼的鏈接。 他提醒觀眾這些都是您可以融入日程安排的10分鐘片段。
Tim在一個普通的C#控制台應用程式中工作 - 可以想像成一個帶有Program類和static void Main(string[] args)的簡單範本文件。 他沒有使用任何特殊的UI框架,只是引用了Spectre.Console的NuGet封包。 這是一個很好的提醒,您可以將這些功能帶入任何Windows Terminal或控制台主機。
創建進度上下文
在0:34,Tim開始編碼。 在他的Main方法中,他調用了AnsiConsole.Progress(),然後在其上調用.Start()。 這是Spectre.Console中進度條的標準入口點。
他顯示您可以傳遞一個帶有上下文參數的lambda,您可以將其視作async ctx,當您之後將它改為異步時。 在這個上下文中您定義您的任務。 這是Spectre.Console等效於在更新之前設置您的進度任務。
添加進度任務
Tim創建了三個進度任務:
"下載數據"
"安裝應用程式"
"數據清理"
每個任務都經由var task = context.AddTask("…")添加。 這些返回了您稍後可以遞增的任務處理器。 Tim在1:22提到他只是觸及表面—Spectre.Console支持不同的樣式、列和佈局,比如添加新的ProgressBarColumn、新的PercentageColumn、新的SpinnerColumn或新的TaskDescriptionColumn來自訂您的進度條外觀。
他將這些任務比作Visual Studio的安裝程式:下載、安裝,然後清理(1:42)。 您可以想像每個任務在內部持有一個int percent或int value進行更新。
更新進度條
在1:50,Tim設置了while循環以運行直到上下文完成。 在實際C控制台程式中,您可能會在Main方法中寫while (!context.IsFinished) 或 while (context.IsFinished == false)。
在循環內,他調用Thread.Sleep(500)來放慢速度(2:15)。 然後他調用task.Increment(),帶有隨機的float乘以最大值(2:29,2:47)。 這模擬了正在進行的工作。
他以不同的速度更新任務一和任務二,對於任務三他添加了一個if檢查(3:05),使其僅在任務二的百分比大於80時開始。這本質上是控制進度任務之間的依賴關係。
雖然Tim沒有真的在foreach循環中鍵入int i,但您可以想像使用一個來迭代任務並為每個叫.increments(int)。 在產品中您可能有真實的數據,例如一個var client下載文件,或者一個正在處理的string filename。 Tim保持簡單使用隨機數字來顯示顯示。
顯示和觀察進度條
在3:47,Tim運行了控制台應用程式。 進度條出現在堆疊中。 每個條在完成時顯示百分比,並變成綠色(4:01)。 一旦第一批任務完成,"數據清理"開始。
在4:14,Tim指出光標返回控制台底部,這是一個小但重要的易用性細節。 Spectre.Console的進度條自動格式化狀態並保持所有東西穩定不閃動。
使用Await Task達到非同步
在4:36,Tim切換到展示異步版本。 他將.Start()改為.StartAsync()並將lambda標記為async。 現在上下文參數行為就像async ctx一樣。
在內部,代替Thread.Sleep,他使用await Task.Delay(500)(4:58)。 這在等待時將控制權交還給系統。 在真實程式中,您可能正在等待一個真實的操作,例如await client.DownloadAsync()或await AnsiConsole.MarkupAsync()以在進度條旁同步顯示狀態文本。
異步版本在視覺上完全相同(5:16–5:23),但更適合現代異步工作流程。 Tim沒有顯示,但您也可以使用try/catch (Exception ex)捕捉例外,包括您的等待中的任務。

AutoClear和完成
Tim注意到默認情況下,Spectre.Console將完成的任務顯示在畫面上達到100%。 如果您希望它們自動消失,可以在設置完成進度後調用.AutoClear(true)(5:42)。 一旦工作完成,條立刻消失(6:02)。

這在您只需要臨時顯示進度報告且不希望雜亂控制台輸出時特別有用。 與交互式提示、新面板顯示,甚至Spectre.Console的var表一起使用,您可以創建一個動態儀表板風格的控制台UI。
超越基礎 – 不同風格和列
在最後的幾分鐘,Tim提到(6:11)還有很多探索空間。 您可以更改格式、顏色、佈局,並使用不同的列類型。例如,您可以添加新的BarChart、新的表格,或將新的面板與進度條結合以顯示分組結果。
Spectre.Console的文檔顯示如何混合新的ProgressColumn實現,或者調整每個任務的最大值,甚至將多個任務折疊成一個條以節省空間("折疊空間")。 您可以用這些來顯示計數、總數、文件名、使用者名或正在處理的密碼 - 全部精美格式化在您的控制台應用程式中。
結論
到他影片結束時,Tim涵蓋了:
從零開始構建的Spectre Console進度條
如何定義和更新多個進度任務
如何使用Thread.Sleep同步執行它或異步使用await Task.Delay
如何使用.AutoClear(true)清除已完成的條
更多高級樣式和文檔去哪裡找
這個小演示展示了您如何輕鬆地將專業的進度條帶入任何C#控制台程式。 只需使用Spectre.Console的NuGet封包和幾行代碼,您就可以顯示狀態、顯示百分比,並為您的使用者提供一個更為清晰的認知您程式在做什麼。
