首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >高精度定时器

高精度定时器
EN

Stack Overflow用户
提问于 2011-08-21 16:02:01
回答 8查看 53.6K关注 0票数 18

我想要一个5毫秒精度的计时器。但目前.Net中的定时器的分辨率约为50ms。我找不到任何可以创建高精度计时器的有效解决方案,尽管有些人声称你可以在C#中实现。

EN

回答 8

Stack Overflow用户

回答已采纳

发布于 2011-08-22 08:06:35

我在下面的博客中找到了这个问题的解决方案:http://web.archive.org/web/20110910100053/http://www.indigo79.net/archives/27#comment-255

它告诉你如何使用多媒体定时器来获得高频率的定时器。它对我来说工作得很好!

票数 7
EN

Stack Overflow用户

发布于 2011-08-21 16:04:07

对于OP专门询问的有关定期触发事件的 Timer 类的信息,可以使用。我已经修改了这个答案,在水平线下面使用了我的旧答案。

我用Timer类测试了下面的代码,似乎在我的机器上它至少可以达到14 - 15毫秒的范围。自己试一试,看看能否重现这一点。因此,低于50毫秒的响应时间是可能的,但它不能精确到1毫秒。

代码语言:javascript
复制
using System;
using System.Timers;
using System.Diagnostics;

public static class Test
{
    public static void Main(String[] args)
    {
        Timer timer = new Timer();
        timer.Interval = 1;
        timer.Enabled = true;

        Stopwatch sw = Stopwatch.StartNew();
        long start = 0;
        long end = sw.ElapsedMilliseconds;

        timer.Elapsed += (o, e) =>
        {
            start = end;
            end = sw.ElapsedMilliseconds;
            Console.WriteLine("{0} milliseconds passed", end - start);
        };

        Console.ReadLine();
    }
}

注:以下是我以前的回答,当时我认为OP是在谈论时间问题。以下仅仅是关于对事件持续时间进行计时的有用信息,但并不提供以固定间隔触发事件的任何方法。为此,Timer类是必需的。

尝试使用System.Diagnostics中的秒表类:http://msdn.microsoft.com/en-us/library/system.diagnostics.stopwatch.aspx

你可以通过它的IsHighResolution字段来查询它,检查它的分辨率是否很高。此外,您还可以检查秒表的精确分辨率:

代码语言:javascript
复制
int resolution = 1E9 / Stopwatch.Frequency;
Console.WriteLine("The minimum measurable time on this system is: {0} nanoseconds", resolution);

如果您担心它的实际来源,文档似乎暗示它实际上在内部调用较低级别的Win32函数:

秒表类帮助操作托管代码中与计时相关的性能计数器。具体地说,可以使用频率字段和GetTimestamp方法代替非托管Win32 APIs和QueryPerformanceCounter。

票数 15
EN

Stack Overflow用户

发布于 2011-08-21 16:03:46

this one呢?

代码语言:javascript
复制
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);
    }
}
票数 11
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7137121

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档