受到黑暗執行序一篇文章《野人獻曝 - 極簡風格 .NET Stopwatch 計時法》的啟發,我延伸了一點小小的功能,讓寫 log 的動作更有彈性一點。原文使用 IDisposable 物件包裝 Stopwatch,在程式碼中以 using 方式使用,在大括號內自動計時,並且在結束的時候寫出 log 內容。在實作 DIspose() 時示範加入 Console.WriteLine 寫出 log 資訊。但如果使用的情境,不一定是要在 Console 或 log 檔案輸出資訊的話呢? 可能是在視窗畫面上顯示資訊。為了達成這樣的目的,我作了小小的修改,在建構子傳入 Action<Stopwatch> 委派,日後就可以依需求自訂 log 處理動作。
/// <summary> /// 以 using 方式包裝 Stopwatch 提供監看程式耗時的功能 /// </summary> public class StopwatchScope : IDisposable { private readonly Stopwatch stopwatch = new Stopwatch(); private Action<Stopwatch> proc; /// <summary> /// 是否停用 /// </summary> public static bool Disabled { get; set; } = false; /// <summary> /// 建構式 /// </summary> /// <param name="stopwatchProcess">StopwatchScope dispose 時候要執行的動作</param> public StopwatchScope(Action<Stopwatch> stopwatchProcess) { if (Disabled) return; proc = stopwatchProcess; stopwatch.Start(); } /// <inheritdoc /> public void Dispose() { if (Disabled) return; stopwatch.Stop(); if (proc != null) proc.Invoke(stopwatch); } } |
使用起來大概像這樣,假設我們有個 Logger 物件專門寫 log 檔案,在 using 建立 StopwatchScope 時,可以傳入寫 log 的方法。
using (StopwatchScope sw = new StopwatchScope(w => {Logger.Write("do something 花費秒數: " + w.Elapsed.TotalSeconds.ToString());}) { // do something } |
呼叫 Logger 寫檔案,也可以替換成更新 Windows UI 某個 label 的內容或是 status bar 的資訊,如此就可以自訂 log 處理動作。