C#如何通过调用QueryPerformanceCounter或GetTickCount64。实现1ms定时1次
时间: 2024-09-27 10:13:35 浏览: 30
在C#中,为了实现1ms级别的高精度定时,通常推荐使用`System.Runtime.InteropServices`命名空间下的`QueryPerformanceCounter`和`QueryPerformanceFrequency`功能,这是Windows API的一部分,能提供非常高的分辨率。`GetTickCount64`虽然也能提供相对较高的精度,但不如`QueryPerformanceCounter`稳定。下面是一个使用`QueryPerformanceCounter`的例子:
```csharp
using System;
using System.Runtime.InteropServices;
class HighPrecisionTimer
{
[DllImport("kernel32.dll", SetLastError = true)]
private static extern bool QueryPerformanceCounter(out ulong lpPerformanceCount);
[DllImport("kernel32.dll", SetLastError = true)]
private static extern bool QueryPerformanceFrequency(out ulong lpFrequency);
private ulong _performanceCount, _frequency;
private long _lastTick;
public HighPrecisionTimer()
{
if (!QueryPerformanceFrequency(out _frequency))
{
throw new Win32Exception(Marshal.GetLastWin32Error());
}
}
public void Start()
{
if (!QueryPerformanceCounter(out _performanceCount))
{
throw new Win32Exception(Marshal.GetLastWin32Error());
}
}
public void TickHandler()
{
if (QueryPerformanceCounter(out ulong currentCount))
{
long elapsedTimeMicroseconds = (_currentCount - _performanceCount) * 1000 / _frequency;
if (elapsedTimeMicroseconds >= 1000)
{
// 处理1ms事件
ProcessOneMillisecondEvent();
_performanceCount = currentCount;
}
}
}
private void ProcessOneMillisecondEvent()
{
Console.WriteLine($"Elapsed: {DateTime.Now.Millisecond} ms");
}
public void StartTimer()
{
_lastTick = DateTime.UtcNow.Ticks;
TickHandler();
}
public void Stop()
{
// 要停止时,无需做额外操作,因为这个模式下,TickHandler会持续被调用直到程序退出
}
}
```
在这个例子中,`TickHandler`会在每经过大约1ms时被触发。但是请注意,不是所有处理器都支持`QueryPerformanceCounter`提供的绝对准确度,因此结果可能会有所差异。在实际应用中,您还需要检查性能计数器是否可靠可用。
阅读全文