# Асинхронное выполнение задач

Так как DayZ - практически полностью однопоточная игра, выполнение длительной задачи (например, чтение файла, парсинг json-файла и т.п.) приводит к блокировке выполнения всего процесса. На клиенте это выражается в зависании приложения и, при достаточно долгой задаче, выходом с сервера. На сервере это выражается в лагах и отключении игроков от сервера. Для решения данной проблемы в MBSL реализован механизм асинхронного выполнения задач, основная идея которого в разделении задачи на мелкие подзадачи и выполнении их не за раз, а на каждом вызове Update.

***Важно: система асинхронного выполнения не гарантирует порядка выполнения задач, поэтому задача, которая была добавлена позже, может выполнится раньше.***

## Класс задачи

Для создания асинхронной задачи необходимо реализовать выполняющий её класс. Базовым классом для таких классов служит MBSL\_AsyncTaskBase, исходный код которого приведён ниже:

```clike
enum MBSL_AsyncTaskStepResult
{
	TaskInProgess,
	TaskWaiting,
	TaskFinished
}

class MBSL_AsyncTaskBase : Managed
{
	MBSL_AsyncTaskStepResult Step(float timeslice);
}
```

Данный класс требует реализации всего одной функции Step, которая принимает один аргумент timeslice - время между предыдущим и предпредыдущим кадром. В этой функции задача должна выполнять одну из своих подзадач, при этом не рекомендуется, чтобы время выполнения превышало 10 мс, иначе теряется смысл асинхронного механизма выполнения.

Функция возвращает одной из значений enum'а MBSL\_AsyncTaskStepResult:

* TaskInProgress - задача выполняла работу на этом вызове Step и ещё не завершила выполнение.
* TaskWaiting - задача не выполняла работу на этом вызове (например, она ждёт чего-то), но ещё не завершила выполнение. **Устаревшее значение, которое более не используется, но оставлено для обратной совместимости.**
* TaskFinished - задача завершила выполнение работы.

## Диспетчер задач

Диспетчер (MBSL\_Dispatcher) - это класс, отвечающий за ведение очереди задач и вызов метода Step на задаче для выполнения. Для его использования требуется всего один метод:

```clike
static void QueueTask(MBSL_AsyncTaskBase task)
```

Данный метод принимает два аргумента:

* task - экземпляр выполняемой задачи.

## Принцип работы диспетчера

Текущая версия диспетчера построена на идее бюджета времени выполнения.

Сервер имеет целевую частоту тиков (TPS - ticks per second) для поддержания стабильной работы. На основе этого значения определяется бюджет времени выполнения для каждого тика (например, при TPS = 60 это значение равно 1/60 = 16 мс). Каждый тик диспетчер определяет уже затраченное игрой время на обработку тика и вычисляется оставшийся бюджет времени.

Диспетчер выдаёт тик максимальному возможному числу задач, не превышая этот бюджет времени. При этом диспетчер ведёт учёт среднего времени тика каждой задачи и использует эту информацию, чтобы определить, умещается ли следующая задача в оставшийся бюджет.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://workshop-guide.magicbyte.ru/mbsl-docs/modeli-vyzova-funkcii/asinkhronnoe-vypolnenie-zadach.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
