How to: Use the High-Resolution Timer
Some devices support a high-resolution timer. This timer, when present, provides more precise measurements than you can obtain by using the TickCount property, which has a 1-millisecond resolution. In applications where precise time measurements are important, the high-resolution timer provides the best results. For example, some Direct3D applications display more smoothly when the animation is based on the high-resolution timer. You can also use this timer in an application to determine how much time a method or a section of code requires to execute.
Example
This code example provides a class that makes it easier to use the high-resolution timer in managed code on Windows CE. The example has the following features:
Platform invoke declarations for the native methods in Windows CE.
A property that is used to get the frequency of the high-resolution counter.
A property that is used to get the value of the high-resolution counter.
An implementation that supports the TickCount property as a fallback if the QueryPerformanceCounter function is not supported or is emulated.
An example of how the high-resolution counter can be used to time an operation.
Public Class HiResTimer
Private isPerfCounterSupported As Boolean = False
Private timerFrequency As Int64 = 0
' Windows CE native library with QueryPerformanceCounter().
Private Const [lib] As String = "coredll.dll"
Public Declare Function QueryPerformanceCounter Lib "Coredll.dll" _
(ByRef count As Int64) As Integer
Public Declare Function QueryPerformanceFrequency Lib "Coredll.dll" _
(ByRef timerFrequency As Int64) As Integer
Public Sub New()
' Query the high-resolution timer only if it is supported.
' A returned frequency of 1000 typically indicates that it is not
' supported and is emulated by the OS using the same value that is
' returned by Environment.TickCount.
' A return value of 0 indicates that the performance counter is
' not supported.
Dim returnVal As Integer = QueryPerformanceFrequency(timerFrequency)
If returnVal <> 0 AndAlso timerFrequency <> 1000 Then
' The performance counter is supported.
isPerfCounterSupported = True
Else
' The performance counter is not supported. Use
' Environment.TickCount instead.
timerFrequency = 1000
End If
End Sub
Public ReadOnly Property Frequency() As Int64
Get
Return timerFrequency
End Get
End Property
Public ReadOnly Property Value() As Int64
Get
Dim tickCount As Int64 = 0
If isPerfCounterSupported Then
' Get the value here if the counter is supported.
QueryPerformanceCounter(tickCount)
Return tickCount
Else
' Otherwise, use Environment.TickCount
Return CType(Environment.TickCount, Int64)
End If
End Get
End Property
Shared Sub Main()
Dim timer As New HiResTimer()
' This example shows how to use the high-resolution counter to
' time an operation.
' Get counter value before the operation starts.
Dim counterAtStart As Int64 = timer.Value
' Perform an operation that takes a measureable amount of time.
Dim count As Integer
For count = 0 To 9999
count += 1
count -= 1
Next count
' Get counter value after the operation ends.
Dim counterAtEnd As Int64 = timer.Value
' Get time elapsed in tenths of milliseconds
Dim timeElapsedInTicks As Int64 = counterAtEnd - counterAtStart
Dim timeElapseInTenthsOfMilliseconds As Int64 = timeElapsedInTicks * 10000 / timer.Frequency
MessageBox.Show("Time Spent in operation (tenths of ms) " + timeElapseInTenthsOfMilliseconds.ToString + vbLf + "Counter Value At Start: " + counterAtStart.ToString + vbLf + "Counter Value At End : " + counterAtEnd.ToString + vbLf + "Counter Frequency : " + timer.Frequency.ToString)
End Sub
End Class
public class HiResTimer
{
private bool isPerfCounterSupported = false;
private Int64 frequency = 0;
// Windows CE native library with QueryPerformanceCounter().
private const string lib = "coredll.dll";
[DllImport(lib)]
private static extern int QueryPerformanceCounter(ref Int64 count);
[DllImport(lib)]
private static extern int QueryPerformanceFrequency(ref Int64 frequency);
public HiResTimer()
{
// Query the high-resolution timer only if it is supported.
// A returned frequency of 1000 typically indicates that it is not
// supported and is emulated by the OS using the same value that is
// returned by Environment.TickCount.
// A return value of 0 indicates that the performance counter is
// not supported.
int returnVal = QueryPerformanceFrequency(ref frequency);
if (returnVal != 0 && frequency != 1000)
{
// The performance counter is supported.
isPerfCounterSupported = true;
}
else
{
// The performance counter is not supported. Use
// Environment.TickCount instead.
frequency = 1000;
}
}
public Int64 Frequency
{
get
{
return frequency;
}
}
public Int64 Value
{
get
{
Int64 tickCount = 0;
if (isPerfCounterSupported)
{
// Get the value here if the counter is supported.
QueryPerformanceCounter(ref tickCount);
return tickCount;
}
else
{
// Otherwise, use Environment.TickCount.
return (Int64)Environment.TickCount;
}
}
}
static void Main()
{
HiResTimer timer = new HiResTimer();
// This example shows how to use the high-resolution counter to
// time an operation.
// Get counter value before the operation starts.
Int64 counterAtStart = timer.Value;
// Perform an operation that takes a measureable amount of time.
for (int count = 0; count < 10000; count+)
{
count++;
count--;
}
// Get counter value when the operation ends.
Int64 counterAtEnd = timer.Value;
// Get time elapsed in tenths of a millisecond.
Int64 timeElapsedInTicks = counterAtEnd - counterAtStart;
Int64 timeElapseInTenthsOfMilliseconds =
(timeElapsedInTicks * 10000) / timer.Frequency;
MessageBox.Show("Time Spent in operation (tenths of ms) "
+ timeElapseInTenthsOfMilliseconds +
"\nCounter Value At Start: " + counterAtStart +
"\nCounter Value At End : " + counterAtEnd +
"\nCounter Frequency : " + timer.Frequency);
}
}
Compiling the Code
This example requires references to the following namespaces:
See Also
Other Resources
Building Applications and Core Tasks in the .NET Compact Framework