Freigeben über


Gewusst wie: Verwenden des hochauflösenden Zeitgebers

Aktualisiert: November 2007

Manche Geräte unterstützen einen hochauflösenden Zeitgeber. Dieser Zeitgeber, sofern vorhanden, kann genauere Messungen durchführen als die, die Sie bei Verwendung der TickCount-Eigenschaft erzielen, welche eine Auflösung von 1 Millisekunde bietet. In Anwendungen, in denen präzise Zeitmessungen wichtig sind, führt der hochauflösende Zeitgeber zu den besten Ergebnissen. Zum Beispiel erzielt man bei einigen Direct3D-Anwendungen ein besseres Anzeigeergebnis, wenn die Animation auf dem hochauflösenden Zeitgeber basiert. Sie können diesen Zeitgeber auch in einer Anwendung verwenden, um festzustellen, wie viel Zeit für die Ausführung einer Methode oder eines Codeabschnitts benötigt wird.

Beispiel

Dieses Codebeispiel enthält eine Klasse, mit deren Hilfe es leichter ist, den hochauflösenden Zeitgeber in verwaltetem Code auf Windows CE zu verwenden. Das Beispiel hat folgende Features:

  • Plattformaufrufdeklarationen für die systemeigenen Methoden in Windows CE.

  • Eine Eigenschaft, die verwendet werden kann, um das Intervall des hochauflösenden Zählers abzurufen.

  • Eine Eigenschaft, die verwendet werden kann, um den Wert des hochauflösenden Zählers abzurufen.

  • Eine Implementierung, die als Fallback die TickCount-Eigenschaft unterstützt, wenn die QueryPerformanceCounter-Funktion nicht unterstützt oder emuliert wird.

  • Ein Beispiel dafür, wie der hochauflösende Zähler verwendet werden kann, um die für eine Operation benötigte Zeit zu bestimmen.

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);
    }
}

Kompilieren des Codes

Für dieses Beispiel sind Verweise auf die folgenden Namespaces erforderlich:

Siehe auch

Weitere Ressourcen

Erstellen von Anwendungen und Kernaufgaben im .NET Compact Framework

Interoperabilität in .NET Compact Framework