實時進度條 - Spectre Console 系列
[[academy-video-youtube({"vid": "vjzwwGfjPP8", "start_time": "0", "title": "Live Progress Bars - Spectre Console Series", "creator": "Tim Corey", "length": "7m 04s"})]]
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(),並用一個隨機的雙精度數乘以一個最大值(2:29, 2:47)。 這模擬了工作正在進行。
他以不同的速度更新任務一和任務二,對於任務三,他新增了一個if檢查(3:05),以便它僅在任務二的百分比大於80時才開始。這本質上是控制進度任務之間的依賴性。
雖然Tim沒有在foreach迴圈中字面上鍵入int i,但您可以想像使用一個迭代任務並為每個調用.Increment(int)。 在生產環境中,您可能會有實際的資料,如var client下載文件,或正在處理的字串檔案名稱。 Tim使用隨機數來簡化顯示。
顯示和觀察進度條
在3:47,Tim運行了控制台應用程式。 進度條以堆疊的形式出現。 每個條形在末尾顯示百分比,完成時變為綠色(4:01)。 一旦第一個任務完成,"資料清理"就開始。
在4:14,Tim指出游標會返回控制台的底部,這是一個小但重要的可用性細節。 Spectre.Console進度條自動格式化狀態並保持一切不閃爍。
使用Await Task實現異步
在4:36,Tim改變了策略來展示一個異步版本。 他將.Start()更改為.StartAsync(),並將lambda標記為異步。 現在上下文參數像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)捕捉您的等待任務周圍的異常。

自動清除並完成
Tim注意到預設情況下Spectre.Console在螢幕上留在100%的完成任務。 如果您希望它們自動消失,請在設置進度後調用.AutoClear(true)(5:42)。 一旦工作完成,條形會立即消失(6:02)。

這在您僅需要暫時顯示進度報告且不希望控制台輸出雜亂時特別有用。 結合互動式提示、新面板顯示,甚至Spectre.Console的var table,您可以建立一個動態儀表板風格的控制台介面。
更高階 – 不同的樣式和列種類
在結束的幾分鐘内,Tim提到(6:11)還有很多可以探索的內容。 您可以更改格式、顏色、佈局並使用不同的列型別。例如,您可以新增一個新的BarChart,一個新的Table,或將一個新的Panel與進度條結合來顯示分組結果。
Spectre.Console的文件顯示如何混合新ProgressColumn實現、或調整每個任務的最大值,甚至將多個任務合併成一個條來節省空間("摺疊空間")。 您可以使用這些來顯示計數、總數、檔名、使用者名或正在處理的密碼——所有這些在您的控制台應用程式中都格式化得很好。
結論
Tim,在他影片結束時涵蓋了:
從零開始構建Spectre Console進度條
如何定義和更新多個進度任務
如何使用Thread.Sleep同步運行或使用await Task.Delay異步運行
如何使用.AutoClear(true)來清除已完成的條形
- 進階樣式和文件的進一步採用
這個小演示展示了您可以多麽輕鬆地將專業外觀的進度條帶入任何C#控制台程式。 只使用Spectre.Console的NuGet包和幾行程式碼,您就可以顯示狀態、顯示百分比,並讓您的使用者更清楚了解您的應用程式在做什麼。

