Вопрос по timer, sleep, .net – Почему минимальный интервал Threading.Timer 15 мс, несмотря на timeBeginPeriod (1)

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

По данным сети, напримеркомментарий Ганса Пассанта, timeBeginPeriod влияет на обычные (.net) таймеры. Так почему мой таймер все еще имеет такую грубую гранулярность?Thread.Sleep кажется, просто отлично.

Может быть уместно: это работает на Windows 7, 64-битной, .net 4, внутри VMWare.

Ваш Ответ

1   ответ
5

что мультимедийный таймер не влияет на таймеры .NET. То есть он не меняет минимальный поддерживаемый период времени, который составляет около 15 мс. Этомог бы улучшить их точность. То есть, если вы просите 16 мс, вы можете получить 16 мс, а не «где-то между 15 и 30 мс».

Почему таймеры .NET ограничены 15 мс, мне непонятно.

Есть некоторая информация об этом в принятом ответеВот.

Если вы ищете таймер с более высоким разрешением для .NET, вам, вероятно, не следует использовать мультимедийные таймеры. Они были объявлены устаревшими в Windows API. Используйте таймеры очереди таймера. Смотрите мои статьи:

Разрешение таймера .NETИзучение вариантов для лучших таймеровИспользование API-интерфейса Windows Timer Queue

Другой вариант заключается в использованииТаймер ожидания, Полный источник для этого доступен вhttp://www.mischel.com/pubs/waitabletimer.zip

Похожие вопросы