使用 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
。
由于缺少 ref 返回值,因此无法直接更改 NativeContainer 的内容。例如,nativeArray[0]++;
与 var temp = nativeArray[0]; temp++;
等效,不会更新 nativeArray
中的值。
正确的做法是,必须将索引中的数据复制到本地临时副本,修改该副本,然后将其存回,如下所示:
MyStruct temp = myNativeArray[i];
temp.memberVariable = 0;
myNativeArray[i] = temp;
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.
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
。最好是调度当前不与正在运行的任何其他作业竞争的、不需要等待的作业。例如,如果在一帧结束和下一帧开始之间的一段时间没有作业正在运行,并且可以接受一帧延迟,则可以在一帧结束时调度作业,并在下一帧中使用其结果。另一方面,如果游戏占满了与其他作业的转换期,但在帧中的其他位置存在大量未充分利用的时段,那么在这个时段调度作业会更加有效。
请注意,默认情况下,作业对 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