reckfellENGINE

Потокобезопасность: дерево Entity, данные и владение

Что оставить в главном потоке, что передать worker и почему mutex или CallDeferred не решают всё.

На этой странице

Практическая граница

Для обычного C# Task или worker оставляйте активное дерево Entity и интерфейс в главном потоке. Передавайте вычислению самостоятельный снимок входа, возвращайте самостоятельный результат и применяйте его после проверки актуальности. Полный пример делает это через _Process.

Объект/операцияПравило для примера и обычного C# worker
Entity в активном дереве, AddChild, удаление, Label/Text и игровое состояниеГлавный поток; не захватывайте их в вычисляющую лямбду
Числа, строки, собственный массив с исключительным владельцемМожно передать worker; после передачи не менять те же данные с другого потока
Общий List/Dictionary, изменение размера коллекцииНужен согласованный протокол блокировки или подходящая concurrent-коллекция; обычная коллекция сама его не даёт
Resource, материал, текстура, PackedEntityСсылка может указывать на общий объект; копия ссылки не является независимой копией данных
Нативный server API, загрузчик, рендеринг и физикаПроверяйте конкретный метод, backend и конфигурацию; общего разрешения «все singleton потокобезопасны» нет

Главный поток в этой таблице не означает, что движок вообще не имеет других режимов обработки. ProcessThreadGroup и внутренние потоки подсистем имеют собственные правила. Обычный Task.Run не входит в разрешённую группу обработки Entity только потому, что выполняется в пуле.

Почему lock недостаточно

lock защищает только тот доступ к вашим данным, при котором все участники берут тот же lock. Он не меняет требование движка вызывать AddChild из главного потока и не заставляет рендерер брать ваш mutex. В стенде реальный вызов AddChild к активному дереву из .NET worker отклоняется движком; проверяется отсутствие добавленного ребёнка.

Отсутствие ошибки в другой сборке не доказывает безопасность: диагностические проверки могут зависеть от конфигурации. Не отключайте проверки потока ради подавления сообщения. Ошибку устраняют изменением владельца и места выполнения операции.

Не держите lock, пока ждёте другую задачу или главный поток. Если главный поток ждёт worker, а worker ждёт действие главного, получается взаимная блокировка. Отмена не может завершить такой цикл, если код не проверяет её или заблокирован на бесконечном ожидании.

Передача результата

CallDeferred ставит вызов в очередь на более позднюю обработку; это не завершённая операция и не обещание определённого следующего кадра. Он не копирует произвольный изменяемый C#-объект и не продлевает жизнь всех ссылок, захваченных вашей лямбдой. Даже при отложенном применении нужны действительный получатель, владелец результата и правило отбрасывания старого запроса.

В BackgroundJob результат читается только после завершения Task в _Process. При выходе из дерева задача отменяется, а её продолжение не трогает Entity. PoolPrimeBatch копирует вход и публикует выход только после join. Это конкретные правила владения, а не проверка существования объекта один раз перед работой на другом потоке.

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

Ресурсы и тяжёлая подготовка

Для загрузки используйте предназначенный для этого API загрузчика, затем создавайте и добавляйте Entity по правилам его жизненного цикла. Не помещайте Instantiate, изменение общего материала и AddChild в Task.Run по аналогии с чистым вычислением чисел. Даже объект вне дерева может ссылаться на общие ресурсы и вызвать серверные операции.

Переносите только подтверждённо независимую часть. Нативная потокобезопасность выбранного метода не отменяет ваши гонки данных, а managed concurrent-коллекция не делает безопасным содержащийся в ней нативный объект. Экспорт, другие backend и специальные группы обработки требуют отдельной проверки.

Документация Reckfell EngineНаверх ↑
БЫСТРЫЙ ПЕРЕХОДНачало работыEntity и иерархияC# & .NET 10Сцены и префабы
Руководства и полный API Reckfell K
reckfellENGINE
RECKFELL ACCOUNT

Вход в аккаунт

Войдите в аккаунт Reckfell.

Один аккаунт для всей платформы Reckfell.