Was this page helpful?
Your feedback about this content is important. Let us know what you think.
Additional feedback?
1500 characters remaining
Export (0) Print
Expand All

HOWTO: Use a Performance Counter

.NET Compact Framework 1.0

Geoff Schwab
Excell Data Corporation

October, 2003

Applies to:
   Microsoft® .NET Compact Framework 1.0

   Microsoft Visual Studio® .NET 2003

Download sample.

Summary: This sample demonstrates how to P/Invoke the QueryPerformanceFrequency and QueryPerformanceCounter functions to create a high resolution timing solution. These functions are OEM specific and in the case that they are not implemented, they default to the GetTickCount function. Therefore, use of these functions should always ensure that the timer is as accurate as possible. When implemented, this functionality can provide much greater accuracy than GetTickCount or Environment.TickCount, the latter of which actually calls the former.


Because the timer resolution varies between devices, the QueryPerformanceFrequency function must be utilized to determine the frequency of the timer. If the return value of this function is 0 then high performance timers are not supported by the hardware. The function takes a single parameter which is a pointer to a 64-bit integer. The function will use the pointer to store the frequency of the timer in the specified location. In the case that the hardware support utilizes GetTickCount, the frequency will be set to 1000, although in the .NET Compact Framework, this is not truly the resolution. Due to the non-deterministic nature of the framework, GetTickCount cannot be guaranteed to a resolution of greater than 500 milliseconds.

The QueryPerformanceCounter function will also return 0 if the OEM has not implemented these timers. In the case that the call is successful, the function's one parameter, also a pointer to a 64-bit integer will be assigned a value, at the specified location, which represents the number of ticks since the machine was turned on. Remember that the ticks are associated with the frequency not a specific time interval.

These functions can be P/Invoked with the following declarations.

public static extern int QueryPerformanceFrequency
    ref Int64 lpFrequency

public static extern int QueryPerformanceCounter
    ref Int64 lpPerformanceCount

<DllImport("CoreDll.dll")> _
Public Shared Function QueryPerformanceFrequency( _
    ByRef lpFrequency As Int64) As Integer
End Function

<DllImport("CoreDll.dll")> _
Public Shared Function QueryPerformanceCounter( _
    ByRef lpPerformanceCount As Int64) As Integer
End Function

To use these functions, simply check their return values and pass them a reference to a 64-bit integer value. The following code demonstrates how to use these functions in conjunction with one another to determine an accurate timer interval.

private void TestTimer()
    System.Int64 freq = 0;
    if (QueryPerformanceFrequency(ref freq) != 0)
        System.Int64 count1 = 0;
        System.Int64 count2 = 0;

        if (QueryPerformanceCounter(ref count1) != 0)
            QueryPerformanceCounter(ref count2);
            System.Int64 time_ms = (count2 - count1) * 1000 / freq;

Private Sub TestTimer()
    Dim freq As System.Int64 = 0

    If QueryPerformanceFrequency(freq) <> 0 Then
        Dim count1 As System.Int64 = 0
        Dim count2 As System.Int64 = 0

        If QueryPerformanceCounter(count1) <> 0 Then

            Dim time_ms As System.Int64
            Time_ms = (count2 - count1) * 1000 / freq
        End If

    End If
End Sub 'TestTimer


The full sample provided with this document loops, repetitively calling Thread.Sleep and timing the interval. These results are displayed in labels on the form. If the performance timers exist on the target hardware then they will generally be much more accurate than GetTickCount or Environment.TickCount.

© 2015 Microsoft