3

以下片段

    [DllImport("winmm.dll", EntryPoint = "timeBeginPeriod")]
    public static extern uint TimeBeginPeriod(uint uMilliseconds);

    static void Main(string[] args)
    {
        if (TimeBeginPeriod(1) != 0)
            Console.WriteLine("TimeBeginPeriod failed!");

        Console.WriteLine("Sleep");
        Stopwatch sw = Stopwatch.StartNew();
        for (int i = 0; i < 10; i++)
        {
            Thread.Sleep(1);
            Console.WriteLine(sw.ElapsedTicks * 1000d / Stopwatch.Frequency);
            sw.Restart();
        }

        Console.WriteLine("Threading.Timer");
        sw = null;
        System.Threading.Timer t = null;
        int n = 0;

        t = new Timer(state =>
        {
            if (sw == null)
                sw = Stopwatch.StartNew();
            else
            {
                Console.WriteLine(sw.ElapsedTicks * 1000d / Stopwatch.Frequency);
                n++;
                sw.Restart();
            }
            if (n == 10)
                t.Change(Timeout.Infinite, Timeout.Infinite);
        }, null, TimeSpan.FromMilliseconds(1), TimeSpan.FromMilliseconds(1));
        Console.ReadKey();
    }

将产生例如这个输出:

Sleep
0.151834939915548
0.757358826331279
0.786901687225611
0.712520725399457
0.715593741662697
0.798704863327602
0.5724889615859
0.648825479215934
0.436927039609783
0.517873081634677
Threading.Timer
15.5841035662354
14.8620145856526
15.1098812837944
14.4202684978119
15.3883384620112
14.7210748852159
15.307462261265
15.7125416777831
14.5991320125882
15.6035194417168

根据网络,例如Hans Passant 的评论timeBeginPeriod会影响常规 (.net) 计时器。那么为什么我的计时器仍然有这种粗粒度呢?Thread.Sleep似乎做得很好。

可能相关:这在 VMWare 内部的 Windows 7、64 位、.net 4 上运行。

4

1 回答 1

5

评论是错误的。我的经验是多媒体计时器不会影响 .NET 计时器。也就是说,它不会改变它们支持的最小时间段,这似乎是大约 15 毫秒。这可能会提高他们的准确性。也就是说,如果您要求 16 毫秒,您实际上可能会得到 16 毫秒,而不是“介于 15 到 30 毫秒之间的某个地方”。

为什么 .NET 计时器限制为 15 毫秒我不清楚。

在此处接受的答案中有一些关于它的信息。

如果您正在为 .NET 寻找更高分辨率的计时器,您可能不应该使用多媒体计时器。这些在 Windows API 中已被弃用。使用定时器队列定时器。看我的文章:

另一种选择是使用Waitable Timer。完整的源代码可在http://www.mischel.com/pubs/waitabletimer.zip获得

于 2013-04-23T13:40:21.760 回答