使用 Unity C# 作业系统时,请确保遵守以下要求:
从作业访问静态数据时会绕过所有安全系统。如果访问错误的数据,通常可能会以意想不到的方式导致 Unity 崩溃。例如,访问 MonoBehaviour 可能会导致在域重新加载时崩溃。
注意:由于存在这种风险,Unity 的未来版本将阻止使用静态分析从作业进行全局变量访问。如果确实要访问作业中的静态数据,则应考虑到您的代码可能会在 Unity 的未来版本中发生中断。
如果希望作业开始执行,则可以使用 JobHandle.ScheduleBatchedJobs 刷新已调度的批次。请注意,调用此方法会对性能产生负面影响。不刷新批次会将调度延迟到主线程等待结果的时候。在所有其他情况下,请使用 JobHandle.Complete 来启动执行过程。
注意:在实体组件系统 (ECS) 中会隐式刷新批次,因此没必要调用 JobHandle.ScheduleBatchedJobs
。
由于缺少 ref 返回值,因此无法直接更改 NativeContainer 的内容。例如,nativeArray[0]++;
与 var temp = nativeArray[0]; temp++;
等效,不会更新 nativeArray
中的值。
正确的做法是,必须将索引中的数据复制到本地临时副本,修改该副本,然后将其存回,如下所示:
MyStruct temp = myNativeArray[i];
temp.memberVariable = 0;
myNativeArray[i] = temp;
要跟踪数据所有权,必须先完成依赖项,然后主线程才能再次使用这些依赖项。仅检查 JobHandle.IsCompleted 是不够的。必须调用 JobHandle.Complete
方法以便将 NativeContainer
类型的所有权重新交还给主线程。调用 Complete
也会清理安全系统中的状态。不这样做会引发内存泄漏。如果在每一帧调度新作业且每一帧依赖于前一帧的作业,此过程也适用。
只能从主线程调用 Schedule 和 Complete
。如果一个作业依赖于另一个作业,请使用 JobHandle
来管理依赖关系,而不是尝试在作业中调度作业。
拥有作业所需的数据后就立即在作业上调用 Schedule
,并仅在需要结果时才开始在作业上调用 Complete
。最好是调度当前不与正在运行的任何其他作业竞争的、不需要等待的作业。例如,如果在一帧结束和下一帧开始之间的一段时间没有作业正在运行,并且可以接受一帧延迟,则可以在一帧结束时调度作业,并在下一帧中使用其结果。另一方面,如果游戏占满了与其他作业的转换期,但在帧中的其他位置存在大量未充分利用的时段,那么在这个时段调度作业会更加有效。
请注意,默认情况下,作业对 NativeContainer
类型具有读写访问权限。请在适当时使用 [ReadOnly]
属性来提高性能。
在 Unity Profiler 窗口中,主线程上的标记“WaitForJobGroup”表示 Unity 正在等待工作线程上的作业完成。此标记可能意味着您已在某处引入了应处理的数据依赖关系。请查找 JobHandle.Complete
来跟踪在何处存在强制主线程等待的数据依赖关系。
作业具有一个 Run 函数,可以使用此函数代替 Schedule
立即在主线程上执行作业。可将此函数用于调试。
在作业中分配托管内存非常慢,而且作业无法使用 Unity Burst 编译器来提高性能。Burst 是一种新的基于 LLVM 的后端编译器技术,可以简化您的工作。此编译器获取 C# 作业并生成高度优化的机器代码,从而利用目标平台的特定功能。
2018–06–15 页面已发布
在 2018.1 版中公开了 C# 作业系统 NewIn20181
Did you find this page useful? Please give it a rating:
Thanks for rating this page!
What kind of problem would you like to report?
Thanks for letting us know! This page has been marked for review based on your feedback.
If you have time, you can provide more information to help us fix the problem faster.
Provide more information
You've told us this page needs code samples. If you'd like to help us further, you could provide a code sample, or tell us about what kind of code sample you'd like to see:
You've told us there are code samples on this page which don't work. If you know how to fix it, or have something better we could use instead, please let us know:
You've told us there is information missing from this page. Please tell us more about what's missing:
You've told us there is incorrect information on this page. If you know what we should change to make it correct, please tell us:
You've told us this page has unclear or confusing information. Please tell us more about what you found unclear or confusing, or let us know how we could make it clearer:
You've told us there is a spelling or grammar error on this page. Please tell us what's wrong:
You've told us this page has a problem. Please tell us more about what's wrong:
Thank you for helping to make the Unity documentation better!
Your feedback has been submitted as a ticket for our documentation team to review.
We are not able to reply to every ticket submitted.