Точность событий C#

Здравствуйте. Решаю тут одну задачку с кодированием видео.
Библиотека openh264-2.0.0-win64.dll.
В целом все нормально но вот вылезла проблема с точностью фпс.
Сделал таймер System.Threading.Timer который по параметрам должен вызывать функцию обработки и выдачи кадра каждые 33,3 мс. Чтобы обеспечить фпс в 30 кадров/с.
Но когда файлик просматриваешь vlc то видно что время видео отличается от нормального.
То есть записываю видео 10 секунд. Получаю файлик на 17 сек.

 Stopwatch stw = new Stopwatch();
            stw.Restart();
            FrameRenderProcess = new System.Threading.Timer(new TimerCallback((o) =>
            {
                stw.Stop();
                double ell = stw.ElapsedMilliseconds; <- тут время выполнения почему то пляшет от 40 до 70
                stw.Restart();
                RenderFrameReady();<- тут время выполнения без записи меньше 1 мс
            }), null, TimeSpan.FromSeconds(1), TimeSpan.FromMilliseconds(33.3));

Я так понимаю что это погрешности срабатывания таймера. Но это же вообще никуда не годится…

Как сделать максимально точный вариант то?? Может быть можно как то подстраивать таймер по какому нибудь алгоритму??

В общем запилил вот так:

FrameRenderThread = new Thread(new ThreadStart(() =>
            {
                Stopwatch stw = new Stopwatch();
                stw.Restart();
                while (!StopRender)
                {
                    stw.Restart();
                    RenderFrameReady();
                    stw.Stop();
                    double waittime = 33 - stw.ElapsedMilliseconds;
                    if (waittime > 0)
                        Thread.Sleep(TimeSpan.FromMilliseconds(waittime));
                }
            }));
            FrameRenderThread.Start();

Может быть костыльно но фпс стал прям то что нужно. Совпадает прям до кадра.
Если у кого нибуь будет более красивое решение буду рад увидеть

А что за кадры? :thinking:
Запись действий в приложении?

Вот статья о том сделать цикл отрисовки для игр:
https://gameprogrammingpatterns.com/game-loop.html

Тут еще несколько вариантов таймеров и объяснение почему так происходит: https://stackoverflow.com/a/34661516/964478
Может быть проще/надежнее выкинуть таймер и сделать while (true) с Application.DoEvents (если это винформс) и проверкой времени.

Так вот во втором примере так и сделал. В потоке. Вроде стабильно.
Это запись видео с нескольких камер+обработка OCV. Не игра. ))
DoEvents говорят с родни GoTo. НЕ особо рекомендуют. Это все на WPF тут тем более такой штуки нету

Ну так если нужен цикл рендеринга с контролем времени, то принципы те же )

Это больше про ситуации типа засовывания его в обработчик клика кнопки, чтоб приложение “не зависало”.
https://stackoverflow.com/a/5183623/964478
Такое лучше решать другими способами, например, async/await. А вот когда нужно больше контроля, то это может быть неплохим вариантом, хотя говорят могут возникнуть проблемы из-за GC: https://gamedev.stackexchange.com/a/67681/115893

Но да, я бы наверно попробовал как-то вынести это в отдельный поток, если с UI не надо ничего делать.

гугл “wpf game loop” советует

То есть видимо в этом событии проверять время и т.д.
Но это наверно имеет смысл только если нужно с UI что-то делать