Cómo: Utilizar el temporizador de alta resolución
Actualización: noviembre 2007
Algunos dispositivos admiten un temporizador de alta resolución. Este temporizador, cuando está presente, proporciona mediciones más precisas que las que pueden obtenerse mediante la propiedad TickCount, que tiene una resolución de 1 milisegundo. En aquellas aplicaciones donde sea importante realizar mediciones de tiempo precisas, el temporizador de alta resolución da los mejores resultados. Por ejemplo, algunas aplicaciones Direct3D se muestran más fácilmente si la animación está basada en el temporizador de alta resolución. Este temporizador puede usarse asimismo en una aplicación para determinar cuánto tiempo requiere la ejecución de un método o una sección de código.
Ejemplo
En este ejemplo de código se proporciona una clase que facilita el uso del temporizador de alta resolución en código administrado en Windows CE. El ejemplo tiene las siguientes características:
Declaraciones de invocación de plataforma para los métodos nativos en Windows CE.
Una propiedad que se utiliza para obtener la frecuencia del contador de alta resolución.
Una propiedad que se utiliza para obtener el valor del contador de alta resolución.
Una implementación que admite la propiedad TickCount como recurso de reserva si la función QueryPerformanceCounter no se admite o se emula.
Un ejemplo de cómo se puede utilizar el contador de alta resolución para cronometrar una operación.
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);
}
}
Compilar el código
Para este ejemplo se requieren referencias a los siguientes espacios de nombres:
Vea también
Otros recursos
Generar aplicaciones y tareas básicas en .NET Compact Framework