2011年8月26日 星期五

C# high resolution/performance counter/timer

The codes show that by using the QueryPerformanceCounter, to implement hight performance/resolution timer and counter. I have tried the from WinForm UI and CLI. The resolution can be 1ms. Of course, this will satisfy us for our normal using.

The code is blow. Enjoy it.

using System;
using System.Runtime.InteropServices;
using System.ComponentModel;
using System.Threading;

namespace HiResTimer
{
    internal class HiPerfTimer
    {
        [DllImport("Kernel32.dll")]
        private static extern bool QueryPerformanceCounter(out long lpPerformanceCount);

        [DllImport("Kernel32.dll")]
        private static extern bool QueryPerformanceFrequency(out long lpFrequency);

        public delegate void CallbackFunction(Object o);
        private long startTime = 0, stopTime = 0;
        private long freq = 0;
        private long interval = 100;
        private bool stop = false;
        private CallbackFunction callback = null;

        // Constructor

        public HiPerfTimer()
        {
            if (QueryPerformanceFrequency(out freq) == false)
            {
                // high-performance counter not supported
                throw new Win32Exception();
            }
        }

        public HiPerfTimer(CallbackFunction callback, long timeInterval)
        {
            if (QueryPerformanceFrequency(out freq) == false)
            {
                // high-performance counter not supported
                throw new Win32Exception();
            }
            this.callback = callback;
            this.interval = timeInterval;
        }

        public void SetCallbackFunction(CallbackFunction callback)
        {
            this.callback = callback;
        }

        public void SetInterval(long interval)
        {
            this.interval = interval;
        }

        // Start the timer
        private void Timer()
        {
            QueryPerformanceCounter(out startTime);
            double checkTimer = (double)interval / 1000.0;
            while(!stop) {
                QueryPerformanceCounter(out stopTime);
                if ((double)(stopTime - startTime) / (double)freq >= checkTimer)
                {
                    // trigger it
                    if (callback != null)
                    {
                        callback(null);
                    }
                    startTime = stopTime;
                }
            }
        }

        public void Start()
        {
            Thread th = new Thread(this.Timer);
            th.Priority = ThreadPriority.Highest;
            th.Start();
        }
        public void Stop()
        {
            stop = true;
        }
    }
}

沒有留言: