C#でWin32APIの呼び出しのサンプルとして、QueryPerformanceCounterを使った高性能タイマープログラムを作成しました。
- 1秒 = 1,000,000 マイクロ秒精度の高性能タイマー
- Tick 毎に 16.666 ms(=1/60秒) を正確に維持
- スリープは誤差が大きいので スピン + Sleep(0) 併用
- WPFでもコンソールでも動く(STA不要)
ソースコード
ファイル名:win32api60fps.csproj
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>
ファイル名:Program.cs
using System;
using System.Runtime.InteropServices;
using System.Threading;
class Program
{
// Win32 API
[DllImport("Kernel32.dll")]
static extern bool QueryPerformanceCounter(out long lpPerformanceCount);
[DllImport("Kernel32.dll")]
static extern bool QueryPerformanceFrequency(out long lpFrequency);
static void Main()
{
if (!QueryPerformanceFrequency(out long freq))
{
Console.WriteLine("High resolution performance counter not supported.");
return;
}
double targetDelta = freq / 60.0; // 60 FPS
Console.WriteLine($"Frequency: {freq} Hz");
Console.WriteLine($"Target delta: {targetDelta} counts");
Console.WriteLine("Start 60 FPS loop...");
QueryPerformanceCounter(out long last);
while (true)
{
// フレーム処理
Update();
// 次のフレームまで busy-wait + Sleep(0)
long current;
while (true)
{
QueryPerformanceCounter(out current);
long diff = current - last;
if (diff >= targetDelta)
break;
// 長すぎる busy-wait を避ける(CPU温存)
Thread.Sleep(0);
}
last = current;
}
}
static void Update()
{
Console.WriteLine($"Frame: {DateTime.Now:HH:mm:ss.fff}");
}
}
結果
Frame: 20:47:29.295
Frame: 20:47:29.311
Frame: 20:47:29.328
Frame: 20:47:29.345
Frame: 20:47:29.361
Frame: 20:47:29.378
Frame: 20:47:29.395
Frame: 20:47:29.411
Frame: 20:47:29.428
Frame: 20:47:29.445
Frame: 20:47:29.461
Frame: 20:47:29.478
Frame: 20:47:29.495
Frame: 20:47:29.511
Frame: 20:47:29.528
Frame: 20:47:29.545
Frame: 20:47:29.561
Frame: 20:47:29.578
Frame: 20:47:29.595
Frame: 20:47:29.611
Frame: 20:47:29.628
Frame: 20:47:29.645
Frame: 20:47:29.661
Frame: 20:47:29.678
Frame: 20:47:29.695
Frame: 20:47:29.711
Frame: 20:47:29.728
Frame: 20:47:29.745
Frame: 20:47:29.761

コメント