C# 高精度定时器
一:常规版
方法A实现了AAAAA...循环执行,且做到A和A之间的时间间隔相同
using System.Diagnostics; using System.Runtime.InteropServices; namespace App10 { internal class Program { private static void MethodA() { // 替换为你的实际方法逻辑 Console.WriteLine($"Method A executed at {DateTime.UtcNow:HH:mm:ss.fffffff}"); } static void Main(string[] args) { var timer = new HighPrecisionTimer(MethodA); timer.Start(); // 运行一段时间后停止 Thread.Sleep(5000); // 运行 5 秒 timer.Stop(); // 等待用户输入以防止程序退出 Console.WriteLine("Press any key to exit..."); Console.ReadKey(); } } public class HighPrecisionTimer { // P/Invoke 声明 [DllImport("winmm.dll", EntryPoint = "timeBeginPeriod", SetLastError = true)] private static extern uint TimeBeginPeriod(uint uMilliseconds); [DllImport("winmm.dll", EntryPoint = "timeEndPeriod", SetLastError = true)] private static extern uint TimeEndPeriod(uint uMilliseconds); private readonly Action _methodToExecute; private readonly double _intervalMs = 0.5; // 目标间隔 0.5ms private volatile bool _isRunning; private readonly uint _timerResolution = 1; // 设置定时器分辨率为 1ms public HighPrecisionTimer(Action method) { _methodToExecute = method ?? throw new ArgumentNullException(nameof(method)); } public void Start() { if (_isRunning) return; _isRunning = true; // 设置高精度定时器分辨率 uint result = TimeBeginPeriod(_timerResolution); if (result != 0) { Console.WriteLine($"Failed to set timer resolution: {result}"); return; } // 在单独线程中运行高精度循环 ThreadPool.QueueUserWorkItem(_ => { var stopwatch = Stopwatch.StartNew(); long nextTick = stopwatch.ElapsedTicks; while (_isRunning) { // 计算下一次执行的时间点(以 ticks 为单位) nextTick += (long)(Stopwatch.Frequency * _intervalMs / 1000.0); // 执行方法 try { _methodToExecute(); } catch (Exception ex) { Console.WriteLine($"Error executing method: {ex.Message}"); } // 自旋等待直到达到目标时间 while (stopwatch.ElapsedTicks < nextTick) { Thread.SpinWait(10); // 短暂自旋,避免过度占用 CPU } // 如果落后太多,重置时间基准以避免累积误差 if (stopwatch.ElapsedTicks > nextTick + (long)(Stopwatch.Frequency * _intervalMs / 1000.0)) { nextTick = stopwatch.ElapsedTicks; } } // 清理定时器分辨率 TimeEndPeriod(_timerResolution); stopwatch.Stop(); }); } public void Stop() { _isRunning = false; } } }

二:进阶版
方法A、方法B实现了ABABABA...循环执行,且做到A和B之间时间间隔相同
using System.IO; using System.Collections.Concurrent; namespace DataSync.DataCore { public class DataProcessor<T> { private readonly ConcurrentBag<T> _dataCollection = new ConcurrentBag<T>(); private readonly string _outputDirectory; private readonly TimeSpan _interval = TimeSpan.FromMinutes(2); private CancellationTokenSource _cts = new CancellationTokenSource(); private DateTime _currentPeriodStart; public DataProcessor(string outputDirectory) { _outputDirectory = outputDirectory ?? throw new ArgumentNullException(nameof(outputDirectory)); Directory.CreateDirectory(_outputDirectory); _currentPeriodStart = AlignToInterval(DateTime.UtcNow); } // 添加数据到集合 public void AddData(T data) { _dataCollection.Add(data); } // 启动处理 public Task StartAsync() { return Task.Run(async () => { while (!_cts.Token.IsCancellationRequested) { DateTime now = DateTime.UtcNow; DateTime nextPeriod = _currentPeriodStart.Add(_interval); if (now >= nextPeriod) { await ProcessDataAsync(); _currentPeriodStart = AlignToInterval(now); } TimeSpan delay = nextPeriod - now; if (delay > TimeSpan.Zero) { await Task.Delay(delay, _cts.Token); } } }, _cts.Token); } // 停止处理 public void Stop() { _cts.Cancel(); _cts.Dispose(); _cts = new CancellationTokenSource(); } // 处理数据并生成文件 private async Task ProcessDataAsync() { if (_dataCollection.IsEmpty) return; var dataToProcess = new ConcurrentBag<T>(); while (_dataCollection.TryTake(out var item)) { dataToProcess.Add(item); } if (dataToProcess.IsEmpty) return; string fileName = Path.Combine(_outputDirectory, $"{_currentPeriodStart:yyyyMMdd_HHmmss}.txt"); try { using (var writer = new StreamWriter(fileName, false)) { foreach (var item in dataToProcess) { await writer.WriteLineAsync(item?.ToString()); } } } catch (Exception ex) { Console.WriteLine($"Error writing to file {fileName}: {ex.Message}"); } } // 对齐到2分钟间隔 private DateTime AlignToInterval(DateTime dt) { long ticks = dt.Ticks / _interval.Ticks; return new DateTime(ticks * _interval.Ticks, dt.Kind); } } }


浙公网安备 33010602011771号