Version: 2021.3
ParallelForTransform 作业
多玩家和联网

C# 作业系统提示和故障排除

使用 Unity C# 作业系统时,请确保遵守以下要求:

不要从作业访问静态数据

从作业访问静态数据时会绕过所有安全系统。如果访问错误的数据,通常可能会以意想不到的方式导致 Unity 崩溃。例如,访问 MonoBehaviour 可能会导致在域重新加载时崩溃。

注意:由于存在这种风险,Unity 的未来版本将阻止使用静态分析从作业进行全局变量访问。如果确实要访问作业中的静态数据,则应考虑到您的代码可能会在 Unity 的未来版本中发生中断。

刷新已调度的批次

When you want your jobs to start executing, then you can flush the scheduled batch with JobHandle.ScheduleBatchedJobs. Note that calling this method can negatively impact performance. Not flushing the batch delays the scheduling until the control thread waits for the result. In all other cases use JobHandle.Complete to start the execution process.

注意:在实体组件系统 (ECS) 中会隐式刷新批次,因此没必要调用 JobHandle.ScheduleBatchedJobs

不要尝试更新 NativeContainer 内容

由于缺少 ref 返回值,因此无法直接更改 NativeContainer 的内容。例如,nativeArray[0]++;var temp = nativeArray[0]; temp++; 等效,不会更新 nativeArray 中的值。

正确的做法是,必须将索引中的数据复制到本地临时副本,修改该副本,然后将其存回,如下所示:

MyStruct temp = myNativeArray[i];
temp.memberVariable = 0;
myNativeArray[i] = temp;

调用 JobHandle.Complete 以重新获得所有权

Tracing data ownership requires dependencies to complete before the control thread can use them again. It is not enough to check JobHandle.IsCompleted. You must call the method JobHandle.Complete to regain ownership of the NativeContainer types to the control thread. Calling Complete also cleans up the state in the safety system. Not doing so introduces a memory leak. This process also applies if you schedule new jobs every frame that has a dependency on the previous frame’s job.

Use Schedule and Complete in the control thread

You can only call Schedule and Complete from the same control thread. If one job depends on another, use JobHandle to manage dependencies rather than trying to schedule jobs within jobs.

在适当时间使用 Schedule 和 Complete 方法

拥有作业所需的数据后就立即在作业上调用 Schedule,并仅在需要结果时才开始在作业上调用 Complete。最好是调度当前不与正在运行的任何其他作业竞争的、不需要等待的作业。例如,如果在一帧结束和下一帧开始之间的一段时间没有作业正在运行,并且可以接受一帧延迟,则可以在一帧结束时调度作业,并在下一帧中使用其结果。另一方面,如果游戏占满了与其他作业的转换期,但在帧中的其他位置存在大量未充分利用的时段,那么在这个时段调度作业会更加有效。

将 NativeContainer 类型标记为只读

请注意,默认情况下,作业对 NativeContainer 类型具有读写访问权限。请在适当时使用 [ReadOnly] 属性来提高性能。

检查数据依赖关系

In the Unity Profiler window, the marker “WaitForJobGroup” on the control thread indicates that Unity is waiting for a job on a worker thread to complete. This marker could mean that you have introduced a data dependency somewhere that you should resolve. Look for JobHandle.Complete to track down where you have data dependencies that are forcing the control thread to wait.

调试作业

Jobs have a Run function that you can use in place of Schedule to immediately execute the job on the control thread. You can use this for debugging purposes.

不要在作业中分配托管内存

在作业中分配托管内存非常慢,而且作业无法使用 Unity Burst 编译器来提高性能。Burst 是一种新的基于 LLVM 的后端编译器技术,可以简化您的工作。此编译器获取 C# 作业并生成高度优化的机器代码,从而利用目标平台的特定功能。

其他信息


  • 2018–06–15 页面已发布

  • 2018.1 版中公开了 C# 作业系统 NewIn20181

ParallelForTransform 作业
多玩家和联网