C# Timer 實現Tick 使用精度問題
我們想在C#中實現一秒鐘執行n次的一個事件, 然後其他方法可以監聽這個事件, 最終實現每一幀隨着Tick改變, 我們的倒計時開始計數.
在使用Timer過程中發現Timer的精度有問題, 最高頻率是1秒調用62次, 不滿足我們的使用需求, 100幀每秒, 於是我們採用了別的方式實現這樣的功能
實現效果
實現誤區
我們最早實現方法是直接開啓一個新線程, 在線程內部開啓一個Timer, 設定Timer的延遲, 但是最終發現它的執行精度最高只能達到62幀每秒, 我就算把Timer的間隔時間設置爲1ms也是隻能執行62幀每秒, 原因我們初步推測是因爲Timer的精度不足.
解決思路
於是我們前往了C#源碼查看, 發現源碼是通過Stopwatch實現的Timer類, Stopwatch類主要是一個倒計時秒錶, 既然知道是什麼東西了那麼就好實現了, 我們開啓一個新線程, 保證線程一直執行就加上無限循環while(true). 在外部 我們開啓Stopwatch, 然後我們在while中判斷秒錶是否達到我們的需求, 如果達到了那麼就調用一個事件, 然後在外部監聽這個事件,就可以實現了
代碼片段
class Program
{
/// <summary>
/// 10ms trigger ont time
/// </summary>
private const int tickTime = 10;
private static Action<long> Tick;
static void Main(string[] args)
{
Tick += (x) => { Console.WriteLine("Time:" + x); };
Thread t = new Thread(() =>
{
Stopwatch s = new Stopwatch();
s.Start();
long temp = 0;
while (true)
{
if (s.ElapsedMilliseconds >= temp + 10)
{
temp = s.ElapsedMilliseconds;
Tick?.Invoke(temp);
}
}
});
t.IsBackground = true;
t.Start();
while (true) { }
}
}
效率
測試上述代碼後發現, 設定爲10ms執行一次的,按照理論上執行次數是1秒鐘100幀, 但實際效果是90幀, 於是我們得出結論, 使用這種方式在10ms的時候, 效率是90%, 然後我們測試了1ms執行一次的效果, 效率爲50%, 也就是1秒鐘執行了500次.