Периодические таймеры в C # и производительности - PullRequest
1 голос
/ 24 апреля 2019

Во многих моих проектах я обнаруживаю, что делаю это:

var thread = new Thread(MyFunc);
thread.Start()

...

MyFunc()
{
    while (true)
    {
        ; Do something
        Thread.Sleep(10);
    }
}

Примером использования может быть опрос API DirectInput для ввода с джойстика.
Это API на основе опроса, не основанный на событиях.

Недавно я изучал, как добиться того же результата, используя современные механизмы - совет, который я получаю, заключается в том, что задачи - это современный способ обработки асинхронного кода.

Итак, я немного покопался в SO и нашел код, который по сути делает это:

_period = 10;
_cancellationTokenSource = new CancellationTokenSource();
while (!_cancellationTokenSource.Token.IsCancellationRequested)
{
    await Task.Delay(_period, _cancellationTokenSource.Token);

    if (!_cancellationTokenSource.Token.IsCancellationRequested)
        _action();
}

Однако, похоже, он использует ОЧЕНЬ больше ЦП.
У меня есть тестпроект здесь , в котором делается попытка сравнить две методики и связанные с ними издержки ЦП, и кажется, что подход, основанный на задачах, использует вдвое больше ЦП
Это первый раз, когда я использовал инструменты тестирования VS perfтем не менее, я мог серьезно ошибиться в интерпретации результатов.
Как я уже упоминал в readme репозитория, для меня важен удар по процессору - он используется для переотображения приложений, которые работают, когда система находится под высокой нагрузкой (Играя в игру).Я готов пожертвовать некоторой производительностью ради более приятного кода, но не вдвое увеличивать нагрузку на процессор.

В репозитории также есть некоторый код для таймера типа «Тайм-аут» (предназначенный для ОЧЕНЬ быстрого сброса), любой вход на него тоже будет оценен.

...