Приостановка потока в C # на более точное время, чем Thread.Sleep - что будет лучшим подходом? - PullRequest
0 голосов
/ 07 ноября 2018

У меня есть этот код:

while(MouseKeyboardStateTest.Keyboard.IsKeyDown(Keys.Space))
{
    Keyboard.KeyPress(Keys.A);
    Thread.Sleep(asChecker.currentDelay);
    for (int i = 0; i <= asChecker.currentMouseClicks; i++)
    {
        Mouse.PressButton(Mouse.MouseKeys.Right);
        Thread.Sleep(globalMouseDelay);
    }
}

И все работает нормально, проблема в том, что Thread.Sleep не является точной, а задержка не всегда одинакова. Есть ли другой способ, которым я мог бы подойти к этому вопросу, чтобы он был точным, по крайней мере, ~ 10 мс?

1 Ответ

0 голосов
/ 07 ноября 2018

Не используйте Thread.Sleep!

Установите KeyPreview формы на true и используйте ключевые события формы.

Это позволит вам получать уведомления о ключевых событиях без задержки и без замораживания интерфейса.

См. Также этот ответ - Winforms: перехват события мыши сначала в главной форме, а не в элементах управления .

Вместо этого вы также можете использовать игровой API. Они позволяют очень быстро реагировать на события мыши и клавиш и не привязаны к элементам управления. Они также позволяют обнаруживать одновременные нажатия клавиш.


Поскольку вы не делаете это в пользовательском интерфейсе (согласно вашему комментарию), я предлагаю другой подход:

В игре вы обычно используете игровой цикл, который зацикливается максимально быстро, без задержки Thread.Sleep. В каждом цикле вы проверяете текущее состояние ввода (клавиатура, мышь, джойстик), обновляете состояние игры и отображаете соответственно.

В каждом цикле сохраняйте текущее время с помощью DateTime.UtcNow (быстрее, чем DateTime.Now) и проверяйте время, прошедшее с момента, когда действие выяснило, достигнута ли необходимая задержка.

Если DateTime недостаточно точен, используйте класс StopWatch. См .: Точность и точность DateTime .

...