酢ろぐ!

カレーが嫌いなスマートフォンアプリプログラマのブログ。

Windows Mobile(.NET Compact Framework)で高分解能タイマを使う

QueryPerformanceFrequency 関数と QueryPerformanceCounter 関数を使用して、Environment.TickCount よりも高い精度を持つ高分解能タイマを作成する事が出来ます。

これらの実装はOEMメーカ固有となっています。

VB.NET

' 以下の名前空間を指定しておいてください
' Imports System.Runtime.InteropServices

Public Class QueryPerformance

    <DllImport("coredll.dll")> _
    Private Shared Function QueryPerformanceCounter(ByRef value As Int64) As Integer
    End Function

    <DllImport("coredll.dll")> _
    Private Shared Function QueryPerformanceFrequency(ByRef value As Int64) As Integer
    End Function

    Public Shared Function GetTime() As Double

        Dim counter As Long = 0
        Dim frequency As Long = 0

        ' 高分解能パフォーマンスカウンタが存在する場合、  
        ' そのカウンタの現在の値を取得します。  
        If (QueryPerformanceCounter(counter) = 0) Then

            ' 高分解能パフォーマンスカウンタが
            ' 実装されていなければ0を返す
            Return 0
        End If

        ' 高分解能パフォーマンスカウンタが存在する場合、  
        ' そのカウンタの周波数(更新頻度)を取得します。  
        ' システムが動作している間は、周波数を変更できません。  
        If (QueryPerformanceFrequency(frequency) = 0) Then

            ' 高分解能パフォーマンスカウンタが
            ' 実装されていなければ0を返す
            Return 0
        End If

        Return counter / frequency
    End Function

End Class

C#

// 以下の名前空間を指定しておいてください
// Imports System.Runtime.InteropServices

public class QueryPerformance
{
    [DllImport("coredll.dll")]
    private static extern int QueryPerformanceCounter(ref Int64 value);

    [DllImport("coredll.dll")]
    private static extern int QueryPerformanceFrequency(ref Int64 value);

    public static double GetTime()
    {
        
        long counter = 0;
        long frequency = 0;
        
        // 高分解能パフォーマンスカウンタが存在する場合、  
        // そのカウンタの現在の値を取得します。  
        if ((QueryPerformanceCounter(counter) == 0)) {
            
            // 高分解能パフォーマンスカウンタが
            // 実装されていなければ0を返す
            return 0;
        }
        
        // 高分解能パフォーマンスカウンタが存在する場合、  
        // そのカウンタの周波数(更新頻度)を取得します。  
        // システムが動作している間は、周波数を変更できません。  
        if ((QueryPerformanceFrequency(frequency) == 0)) {
            
            // 高分解能パフォーマンスカウンタが
            // 実装されていなければ0を返す
            return 0;
        }
        
        return counter / frequency;
    }
}