Я пытаюсь выполнять обратный вызов C# каждые 10 мс с точностью до 1 мс, если это возможно. На данный момент в моем проекте я просто использую цикл вращения и секундомер, и мне удалось достичь желаемого результата с отклонением менее 1 мс, но он потребляет 100% ядра процессора, что не идеально. Я ищу решение, чтобы избежать этого, и наткнулся на тему, в которой рассказывается о методе C CreateTimerQueueTimer, дополнительную информацию можно найти здесь.
Я создал следующий скрипт ниже чтобы проверить это в Unity, но по какой-то причине я не могу получить таймер с интервалом менее 15 мс. Точность выглядит очень хорошей, но мне нужно, чтобы она была ниже 15 мс. Я попытался использовать timeBeginPeriod, как было предложено здесь, но это ничего не изменило. Я делаю что-то не так в своем коде или это неправильный способ?
using System.Runtime.InteropServices;
using System;
using UnityEditor;
using UnityEngine;
public static class TestHighResTimer {
private static readonly string debug_id = "[HighRes Timer]";
private static System.Diagnostics.Stopwatch sw;
private static int count = 0;
private static IntPtr timer = IntPtr.Zero;
[InitializeOnLoadMethod]
private static void Init()
{
//Setup some callback so that we don't crash when editing code, reloading domain ect...
AssemblyReloadEvents.beforeAssemblyReload += Destroy;
EditorApplication.update += StartTimer;
EditorApplication.update += EditorUpdate;
Debug.Log($"{debug_id} Init");
}
private static void Destroy()
{
Debug.Log($"{debug_id} Destroy");
EditorApplication.update -= EditorUpdate;
}
private static void StartTimer()
{
EditorApplication.update -= StartTimer;
Debug.Log($"{debug_id} Start");
//Prepare the stopwatch and count to measure the callback interval
sw = new System.Diagnostics.Stopwatch();
count = 0;
timeBeginPeriod(1); //It is supposed to improved accuracy of timer event but I didn't notice a change...
CreateTimerQueueTimer(out timer, IntPtr.Zero, TimerCallback, IntPtr.Zero, 1, 10, 0); //Start a timer to fire the callback every 10ms
}
private static void EditorUpdate()
{
//We limit the test at 1000 iterations otherwise it will run indefinitely
if(count > 1000)
{
DeleteTimerQueueTimer(IntPtr.Zero, timer, IntPtr.Zero); //Clear the timer
timeEndPeriod(1);
count = 0;
}
}
private static void TimerCallback(IntPtr p, bool b)
{
Debug.Log($"{debug_id} Tick : {sw.Elapsed.TotalMilliseconds} [ms]");
sw.Restart();
count++;
}
public delegate void WaitOrTimerDelegate(IntPtr lpParameter, bool TimerOrWaitFired);
[DllImport("kernel32.dll")]
static extern bool CreateTimerQueueTimer(out IntPtr phNewTimer, IntPtr TimerQueue, WaitOrTimerDelegate Callback,
IntPtr Parameter, uint DueTime, uint Period, uint Flags);
[DllImport("kernel32.dll")]
static extern bool DeleteTimerQueueTimer(IntPtr TimerQueue, IntPtr Timer, IntPtr CompletionEvent);
[DllImport("winmm.dll")]
public static extern uint timeBeginPeriod(int msec);
[DllImport("winmm.dll")]
public static extern uint timeEndPeriod(int msec);
}
Подробнее здесь: https://stackoverflow.com/questions/792 ... queuetimer
C# Unity — таймер высокой точности с использованием TimerQueueTimer ⇐ C#
Место общения программистов C#
-
Anonymous
1733392406
Anonymous
Я пытаюсь выполнять обратный вызов C# каждые 10 мс с точностью до 1 мс, если это возможно. На данный момент в моем проекте я просто использую цикл вращения и секундомер, и мне удалось достичь желаемого результата с отклонением менее 1 мс, но он потребляет 100% ядра процессора, что не идеально. Я ищу решение, чтобы избежать этого, и наткнулся на тему, в которой рассказывается о методе C [b]CreateTimerQueueTimer[/b], дополнительную информацию можно найти здесь.
Я создал следующий скрипт ниже чтобы проверить это в Unity, но по какой-то причине я не могу получить таймер с интервалом менее 15 мс. Точность выглядит очень хорошей, но мне нужно, чтобы она была ниже 15 мс. Я попытался использовать [b]timeBeginPeriod[/b], как было предложено здесь, но это ничего не изменило. Я делаю что-то не так в своем коде или это неправильный способ?
using System.Runtime.InteropServices;
using System;
using UnityEditor;
using UnityEngine;
public static class TestHighResTimer {
private static readonly string debug_id = "[HighRes Timer]";
private static System.Diagnostics.Stopwatch sw;
private static int count = 0;
private static IntPtr timer = IntPtr.Zero;
[InitializeOnLoadMethod]
private static void Init()
{
//Setup some callback so that we don't crash when editing code, reloading domain ect...
AssemblyReloadEvents.beforeAssemblyReload += Destroy;
EditorApplication.update += StartTimer;
EditorApplication.update += EditorUpdate;
Debug.Log($"{debug_id} Init");
}
private static void Destroy()
{
Debug.Log($"{debug_id} Destroy");
EditorApplication.update -= EditorUpdate;
}
private static void StartTimer()
{
EditorApplication.update -= StartTimer;
Debug.Log($"{debug_id} Start");
//Prepare the stopwatch and count to measure the callback interval
sw = new System.Diagnostics.Stopwatch();
count = 0;
timeBeginPeriod(1); //It is supposed to improved accuracy of timer event but I didn't notice a change...
CreateTimerQueueTimer(out timer, IntPtr.Zero, TimerCallback, IntPtr.Zero, 1, 10, 0); //Start a timer to fire the callback every 10ms
}
private static void EditorUpdate()
{
//We limit the test at 1000 iterations otherwise it will run indefinitely
if(count > 1000)
{
DeleteTimerQueueTimer(IntPtr.Zero, timer, IntPtr.Zero); //Clear the timer
timeEndPeriod(1);
count = 0;
}
}
private static void TimerCallback(IntPtr p, bool b)
{
Debug.Log($"{debug_id} Tick : {sw.Elapsed.TotalMilliseconds} [ms]");
sw.Restart();
count++;
}
public delegate void WaitOrTimerDelegate(IntPtr lpParameter, bool TimerOrWaitFired);
[DllImport("kernel32.dll")]
static extern bool CreateTimerQueueTimer(out IntPtr phNewTimer, IntPtr TimerQueue, WaitOrTimerDelegate Callback,
IntPtr Parameter, uint DueTime, uint Period, uint Flags);
[DllImport("kernel32.dll")]
static extern bool DeleteTimerQueueTimer(IntPtr TimerQueue, IntPtr Timer, IntPtr CompletionEvent);
[DllImport("winmm.dll")]
public static extern uint timeBeginPeriod(int msec);
[DllImport("winmm.dll")]
public static extern uint timeEndPeriod(int msec);
}
Подробнее здесь: [url]https://stackoverflow.com/questions/79252139/c-sharp-unity-high-precision-timer-using-timerqueuetimer[/url]
Ответить
1 сообщение
• Страница 1 из 1
Перейти
- Кемерово-IT
- ↳ Javascript
- ↳ C#
- ↳ JAVA
- ↳ Elasticsearch aggregation
- ↳ Python
- ↳ Php
- ↳ Android
- ↳ Html
- ↳ Jquery
- ↳ C++
- ↳ IOS
- ↳ CSS
- ↳ Excel
- ↳ Linux
- ↳ Apache
- ↳ MySql
- Детский мир
- Для души
- ↳ Музыкальные инструменты даром
- ↳ Печатная продукция даром
- Внешняя красота и здоровье
- ↳ Одежда и обувь для взрослых даром
- ↳ Товары для здоровья
- ↳ Физкультура и спорт
- Техника - даром!
- ↳ Автомобилистам
- ↳ Компьютерная техника
- ↳ Плиты: газовые и электрические
- ↳ Холодильники
- ↳ Стиральные машины
- ↳ Телевизоры
- ↳ Телефоны, смартфоны, плашеты
- ↳ Швейные машинки
- ↳ Прочая электроника и техника
- ↳ Фототехника
- Ремонт и интерьер
- ↳ Стройматериалы, инструмент
- ↳ Мебель и предметы интерьера даром
- ↳ Cантехника
- Другие темы
- ↳ Разное даром
- ↳ Давай меняться!
- ↳ Отдам\возьму за копеечку
- ↳ Работа и подработка в Кемерове
- ↳ Давай с тобой поговорим...
Мобильная версия