Перезапускаемые задачи с синхронизацией - PullRequest
0 голосов
/ 07 апреля 2020

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

Для повышения производительности на стороне клиента я могу sh очистить (скрыть или удалить) объекты, которые не были обновлены в течение X раз.

Я пришел к следующей идее:

Реализация механизма похож на JavaScript х setTimeout. Механизм должен поддерживать промежуточное завершение, а также перезапуск с тем же набором аргументов.

Я думал о создании class, который реализует Task и принимает ushort в качестве интервала времени ожидания, и Action / Функция, которую нужно выполнить после того, как прошло время.

Я буду ссылаться на вышеуказанный класс как TimedTask.

TimedTask будет иметь 2 внутренних потока / задачи: 1. поток / задача1 будет отвечает за режим сна до истечения времени ожидания 2. поток / задача 2 будет отвечать за получение команд промежуточного уровня (например, перезапуск, остановка, завершение)

TimedTask может прожить долгое время и это зависит от обстоятельств, и может быть параллельно запущено более 20-100 TimedTask с.

Боюсь, что приведенная выше реализация вызовет серьезные проблемы с производительностью, и, возможно, найдется лучший способ решить эту проблему, должен ли я oop просмотреть каждый сетевой объект, который есть у моего клиента на каждом тике, и посмотреть, какие из них не были обновлены? .

1 Ответ

0 голосов
/ 08 апреля 2020

Взгляните на класс PauseTokenSource Стивена Тауба (также доступен в пакете AsyncEx.Coordination от StephenCleary). Вы можете иметь сотни долгоживущих задач, каждая из которых контролируется отдельным PauseTokenSource. Производительность будет зависеть от того, что вы делаете внутри каждой задачи. Затраты на механизм приостановки должны быть незначительными, если вы не ожидаете частоту ~ 100 000 циклов в секунду или более (для всех задач в целом).

using Nito.AsyncEx;

async Task CreateLongLivedTask(PauseToken pauseToken, CancellationToken cancellationToken)
{
    while (true)
    {
        await pauseToken.WaitWhilePausedAsync(cancellationToken);
        DoImportantStuff();
        await Task.Delay(100, cancellationToken); // 10 loops per second
    }
}
...