C# 通过Stopwatch 微秒时钟实现
发布时间:2025-06-26 06:22 浏览量:1
在某些高精度计时场景中,我们可能需要一个能够精确到微秒级别的时钟或定时器。虽然 C# 和 .NET 框架本身并不直接提供微秒级别的时钟,但我们可以利用 Stopwatch 类来创建一个高精度的时钟和定时器。本文将介绍如何实现一个微秒级的时钟,以及如何将其封装成一个类似 System.Timer 的功能。
首先,让我们实现一个基本的微秒级时钟:
using System;using System.Diagnostics;public class MicrosecondClock{private readonly stopwatch stopwatch;private readonly DateTime startTime;public MicrosecondClock{stopwatch = new Stopwatch;startTime = DateTime.Now;stopwatch.Start;}public DateTime Now{get{long ticks = stopwatch.Elapsed.Ticks;return startTime.AddTicks(ticks);}}public string GetFormattedTime{DateTime now = Now;long microseconds = stopwatch.Elapsed.Ticks / (TimeSpan.TicksPerMillisecond / 1000);return $"{now:yyyy-MM-dd HH:mm:ss}.{microseconds:D6}";}}这个 MicrosecondClock 类使用 Stopwatch 来测量经过的时间,精确到 ticks(1 tick = 100 纳秒)。它提供了两个主要方法:
Now 属性返回当前时间,精确到 tick。GetFormattedTime 方法返回一个格式化的字符串,显示当前时间精确到微秒。接下来,我们将实现一个类似 System.Timer 的微秒级定时器:
using System;using System.Diagnostics;using System.Threading;using System.Threading.Tasks;public class MicrosecondTimer : IDisposable{private readonly Stopwatch stopwatch;private long interval;private bool enabled;private Task timerTask;private CancellationTokenSource cancellationTokenSource;public event EventHandlerElapsed; public MicrosecondTimer { stopwatch = new Stopwatch; interval = Stopwatch.Frequency / 1000; // 默认1毫秒 enabled = false; } public bool Enabled { get => enabled; set { if (enabled != value) { enabled = value; if (enabled) Start; else Stop; } } } public long Interval { get => interval * 1000000 / Stopwatch.Frequency; set => interval = value * Stopwatch.Frequency / 1000000; } private void Start { cancellationTokenSource = new CancellationTokenSource; timerTask = Task.Run(TimerLoop, cancellationTokenSource.Token); } private void Stop { cancellationTokenSource?.Cancel; timerTask?.Wait; } private async Task TimerLoop { stopwatch.Restart; while (!cancellationTokenSource.Token.IsCancellationRequested) { long elapsedTicks = stopwatch.ElapsedTicks; if (elapsedTicks >= interval) { OnElapsed(new MicrosecondTimerEventArgs(elapsedTicks * 1000000 / Stopwatch.Frequency)); stopwatch.Restart; } await Task.Delay(1); } } protected virtual void OnElapsed(MicrosecondTimerEventArgs e) { Elapsed?.Invoke(this, e); } public void Dispose { Stop; cancellationTokenSource?.Dispose; } } public class MicrosecondTimerEventArgs : EventArgs { public long ElapsedMicroseconds { get; } public MicrosecondTimerEventArgs(long elapsedMicroseconds) { ElapsedMicroseconds = elapsedMicroseconds; } }这个 MicrosecondTimer 类提供了以下功能:
Enabled 属性用于启动或停止定时器。Interval 属性设置定时器的间隔,以微秒为单位。Elapsed 事件在每次定时器触发时被引发。使用 Task 和 CancellationTokenSource 来控制定时器的运行。下面是如何使用这些类的示例:
class Program{static void Main{// 使用 MicrosecondClockMicrosecondClock clock = new MicrosecondClock;Console.WriteLine($"Current time: {clock.GetFormattedTime}");// 使用 MicrosecondTimerusing (var timer = new MicrosecondTimer){timer.Interval = 1000; // 设置为1000微秒(1毫秒)timer.Elapsed += (sender, e) =>{Console.WriteLine($"Timer elapsed: {e.ElapsedMicroseconds} microseconds");};timer.Enabled = true;Console.WriteLine("Press any key to stop the timer...");Console.ReadKey;}}}在使用这些高精度时钟和定时器时,需要注意以下几点:
实际精度受限于硬件和操作系统。虽然代码可以提供微秒级的精度,但不同系统的实际表现可能有所不同。对于非常短的时间间隔(如几微秒),可能无法保证准确性,因为事件处理和任务调度本身就需要一定的时间。MicrosecondTimer 在后台使用一个持续运行的任务,可能会消耗一定的系统资源。对于需要长时间运行或需要大量实例的场景,可能需要考虑更优化的实现。在多线程环境中使用时,需要注意事件处理程序的线程安全性。长时间运行可能会积累误差。对于需要长期精确计时的应用,可能需要定期与系统时钟同步。通过使用 Stopwatch 类和一些巧妙的编程技巧,我们可以在 C# 中实现微秒级的时钟和定时器。这些实现可以在需要高精度计时的场景中发挥作用,如性能测试、科学计算或某些实时系统。然而,在使用这些高精度工具时,务必要考虑到硬件和操作系统的限制,以及潜在的性能影响。