Haukcode.HighResolutionTimer
High Resolution Timer for .NET Core
Install / Use
/learn @HakanL/Haukcode.HighResolutionTimerREADME
Haukcode.HighResolutionTimer 
A high-resolution, cross-platform timer for .NET Standard 2.0+ applications that provides precise timing capabilities for Windows, Linux, and macOS.
Overview
Haukcode.HighResolutionTimer is a lightweight library that abstracts platform-specific high-resolution timer implementations to provide consistent, precise timing across different operating systems:
- Windows: Uses Waitable Timer API (
SetWaitableTimer) with sub-millisecond precision - Linux: Uses
timerfdAPI with microsecond precision - macOS: Uses
kqueue/keventAPI with microsecond precision - Cross-platform: Automatic platform detection and selection
This library is ideal for applications requiring accurate periodic execution, such as real-time data processing, game loops, multimedia applications, or any scenario where System.Threading.Timer doesn't provide sufficient precision.
Features
- ✅ Cross-platform support (Windows, Linux, and macOS)
- ✅ High precision timing (sub-millisecond on all platforms)
- ✅ Simple, intuitive API
- ✅ Automatic platform detection
- ✅ Support for both 32-bit and 64-bit Linux
- ✅ .NET Standard 2.0 compatible
- ✅ Configurable timer period
- ✅ Thread-safe implementation
- ✅ Disposable pattern for proper resource cleanup
Installation
Install via NuGet Package Manager:
dotnet add package Haukcode.HighResolutionTimer
Or via Package Manager Console:
Install-Package Haukcode.HighResolutionTimer
Or add directly to your .csproj file:
<PackageReference Include="Haukcode.HighResolutionTimer" Version="1.*" />
Quick Start
Here's a simple example to get you started:
using Haukcode.HighResolutionTimer;
using System;
class Program
{
static void Main()
{
// Create a timer with 10ms period (100 Hz)
using (var timer = new HighResolutionTimer())
{
timer.SetPeriod(10); // 10 milliseconds
timer.Start();
// Run for 1 second
for (int i = 0; i < 100; i++)
{
timer.WaitForTrigger();
Console.WriteLine($"Tick {i} at {DateTime.Now:HH:mm:ss.fff}");
}
timer.Stop();
}
}
}
Usage Examples
Basic Timer with Custom Period
using (var timer = new HighResolutionTimer())
{
// Set period to 25ms (40 Hz)
timer.SetPeriod(25);
timer.Start();
for (int i = 0; i < 10; i++)
{
timer.WaitForTrigger();
// Your periodic code here
Console.WriteLine("Tick!");
}
timer.Stop();
}
Real-Time Data Processing Loop
using (var timer = new HighResolutionTimer())
{
timer.SetPeriod(1); // 1ms period for high-frequency processing
timer.Start();
bool keepRunning = true;
while (keepRunning)
{
timer.WaitForTrigger();
// Process real-time data
ProcessSensorData();
// Check exit condition
if (Console.KeyAvailable)
{
keepRunning = false;
}
}
timer.Stop();
}
Game Loop Example
using (var timer = new HighResolutionTimer())
{
const double targetFPS = 60.0;
double framePeriod = 1000.0 / targetFPS; // ~16.67ms
timer.SetPeriod(framePeriod);
timer.Start();
bool running = true;
while (running)
{
timer.WaitForTrigger();
// Update game state
UpdateGameLogic();
// Render frame
RenderFrame();
// Check for exit
running = !ShouldExit();
}
timer.Stop();
}
Async/Await Pattern
public async Task RunTimerAsync(CancellationToken cancellationToken)
{
using (var timer = new HighResolutionTimer())
{
timer.SetPeriod(100); // 100ms
timer.Start();
try
{
while (!cancellationToken.IsCancellationRequested)
{
await Task.Run(() => timer.WaitForTrigger(), cancellationToken);
// Your periodic work
await DoWorkAsync();
}
}
finally
{
timer.Stop();
}
}
}
API Reference
HighResolutionTimer Class
The main class implementing ITimer and IDisposable interfaces.
Constructor
public HighResolutionTimer()
Creates a new high-resolution timer instance. Automatically selects the appropriate platform-specific implementation.
Methods
SetPeriod
public void SetPeriod(double periodMS)
Sets the timer period in milliseconds.
- Parameters:
periodMS(double): Period in milliseconds. Must be greater than 0 and less than 15 minutes (900,000 ms).
- Throws:
ArgumentOutOfRangeException: If period is out of valid range.
Example:
timer.SetPeriod(10); // 10ms period (100 Hz)
timer.SetPeriod(1); // 1ms period (1000 Hz)
timer.SetPeriod(16.67); // ~60 Hz (common for games)
Start
public void Start()
Starts the timer. Must be called before WaitForTrigger().
- Throws:
InvalidOperationException: If timer is already running.
Stop
public void Stop()
Stops the timer. Can be started again with Start().
- Throws:
InvalidOperationException: If timer is not running.
WaitForTrigger
public void WaitForTrigger()
Blocks the current thread until the next timer event occurs. This method should be called in a loop to process periodic events.
Important: Must call Start() before using this method.
Dispose
public void Dispose()
Releases all resources used by the timer. Automatically stops the timer if running.
Platform-Specific Details
Windows Implementation
- Uses Windows Waitable Timer API (
kernel32.dll) - Sub-millisecond precision: period stored as 100-nanosecond intervals, so fractional values like 16.67ms work correctly
- Scheduler thread manually re-arms the timer each period, matching the Linux/macOS approach
- Works on all Windows versions that support .NET Standard 2.0
Linux Implementation
- Uses
timerfd_createandtimerfd_settimesystem calls - Precision: Microsecond level
- Separate implementations for 32-bit and 64-bit systems
- Requires Linux kernel 2.6.25 or later (timerfd support)
macOS Implementation
- Uses
kqueue/keventsystem calls withNOTE_USECONDSflag - Precision: Microsecond level
- Works on all macOS versions that support .NET Standard 2.0
Performance Considerations
Precision vs. CPU Usage
- Lower period values (higher frequencies) increase CPU usage
- On Windows, the Waitable Timer uses the default system timer resolution
- Consider your application's actual timing requirements
Best Practices
- Use appropriate periods: Don't use 1ms if 10ms will suffice
- Dispose properly: Always use
usingstatement or callDispose()when done - Avoid blocking operations: Keep work in
WaitForTrigger()loop minimal - Consider threading: For heavy work, consider offloading to separate threads
- Test on target platform: Timing precision can vary by hardware and OS
Example with Performance Measurement
using System.Diagnostics;
using (var timer = new HighResolutionTimer())
{
timer.SetPeriod(10); // 10ms target
timer.Start();
var stopwatch = Stopwatch.StartNew();
long lastElapsed = 0;
for (int i = 0; i < 100; i++)
{
timer.WaitForTrigger();
long currentElapsed = stopwatch.ElapsedMilliseconds;
long actualPeriod = currentElapsed - lastElapsed;
lastElapsed = currentElapsed;
Console.WriteLine($"Tick {i}: Actual period = {actualPeriod}ms");
}
timer.Stop();
}
Requirements
- .NET Standard 2.0 or higher
- Compatible with:
- .NET Core 2.0+
- .NET 5+
- .NET Framework 4.6.1+
- Mono 5.4+
- Xamarin
- Windows or Linux or macOS operating system
Limitations
- Period must be between 0 and 15 minutes (900,000 ms)
- Timer precision depends on OS and hardware capabilities
- High-frequency timers (< 5ms) may impact overall system performance
Troubleshooting
Common Issues
Timer not triggering on Linux:
- Ensure your kernel version supports timerfd (Linux 2.6.25+)
- Check permissions if running in a restricted environment
Inconsistent timing on Windows:
- Other applications may affect timer resolution
- Consider increasing the timer period for better CPU efficiency
High CPU usage:
- Consider increasing the timer period
- Ensure work in the timer loop is minimal
- Profile your application to identify bottlenecks
Contributing
Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.
Development Setup
-
Clone the repository:
git clone https://github.com/HakanL/Haukcode.HighResolutionTimer.git -
Build the project:
cd Haukcode.HighResolutionTimer/src dotnet build -
Run tests (if available):
dotnet test
License
This project is licensed under the MIT License - see the LICENSE file for details.
Acknowledgments
- Uses Windows Waitable Timer API for high-resolution timing on Windows
- Uses Linux timerfd API for precise timing on Linux
- Uses macOS kqueue/kevent API for precise timing on macOS
- Inspired by the need for cross-platform high-resolution timing in .NET applications
Support
- Issues: GitHub Issues
- NuGet Package: [Haukcode.HighResolutionTimer](https:/
Related Skills
node-connect
345.9kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
frontend-design
106.4kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
openai-whisper-api
345.9kTranscribe audio via OpenAI Audio Transcriptions API (Whisper).
qqbot-media
345.9kQQBot 富媒体收发能力。使用 <qqmedia> 标签,系统根据文件扩展名自动识别类型(图片/语音/视频/文件)。
