使用 Job.WithCode
SystemBase类提供的Job.WithCode构造是一种将函数作为单个后台作业运行的简单方法。您还可以在主线程上运行Job.WithCode并仍然利用Burst编译来加速执行。
以下示例使用一个Job.WithCode lambda 函数用随机数填充本机数组,并使用另一个作业将这些数字相加:
public partial class RandomSumJob : SystemBase
{
private uint seed = 1;
protected override void OnUpdate()
{
Random randomGen = new Random(seed++);
NativeArray<float> randomNumbers
= new NativeArray<float>(500, Allocator.TempJob);
Job.WithCode(() =>
{
for (int i = 0; i < randomNumbers.Length; i++)
{
randomNumbers[i] = randomGen.NextFloat();
}
}).Schedule();
// To get data out of a job, you must use a NativeArray
// even if there is only one value
NativeArray<float> result
= new NativeArray<float>(1, Allocator.TempJob);
Job.WithCode(() =>
{
for (int i = 0; i < randomNumbers.Length; i++)
{
result[0] += randomNumbers[i];
}
}).Schedule();
// This completes the scheduled jobs to get the result immediately, but for
// better efficiency you should schedule jobs early in the frame with one
// system and get the results late in the frame with a different system.
this.CompleteDependency();
UnityEngine.Debug.Log("The sum of "
+ randomNumbers.Length + " numbers is " + result[0]);
randomNumbers.Dispose();
result.Dispose();
}
}
笔记
要运行并行作业,请实现IJobFor,您可以使用系统OnUpdate()函数中的ScheduleParallel()进行调度。
变量
您不能将参数传递给Job.WithCode lambda 函数或返回值。相反,您可以在OnUpdate()函数中捕获局部变量。
当你计划你的工作在运行C#作业系统使用Schedule()
,还有额外的限制:
- 捕获的变量必须声明为 NativeArray —— 或其他本机容器—— 或blittable类型。
- 要返回数据,您必须将返回值写入捕获的本机数组,即使数据是单个值。(请注意,您可以在使用
Run()
.执行时写入任何捕获的变量。)
Job.WithCode提供了一组函数来将只读和安全属性应用于捕获的本机容器变量。例如,您可以使用WithReadOnly
指定不更新容器并WithDisposeOnCompletion
在作业完成后自动处置容器。(Entities.ForEach提供相同的功能。)
有关这些修饰符和属性的更多信息,请参见Job.WithCode。
执行函数
您有两个选项可以执行 lambda 函数:
Schedule()
-- 将函数作为单个非并行作业执行。调度作业在后台线程上运行代码,因此可以更好地利用可用的 CPU 资源。Run()
-- 立即在主线程上执行函数。在大多数情况下,Job.WithCode可以被Burst编译,因此即使它仍然在主线程上运行,在Job.WithCode 中执行代码也可以更快。
注意调用会Run()
自动完成Job.WithCode构造的所有依赖。如果您没有显式地将JobHandle对象传递给Run()
系统,则假定当前的Dependency属性表示函数的依赖项。(如果函数没有依赖项,则传入一个新的JobHandle。)
依赖关系
默认情况下,系统使用其Dependency属性管理其与 ECS 相关的依赖项。系统将使用Entities.ForEach和Job.WithCode创建的每个作业按照它们在OnUpdate()函数中出现的顺序添加到依赖作业句柄。您还可以通过将JobHandle传递给您的函数来手动管理作业依赖项,然后返回生成的依赖项。有关更多信息,请参阅依赖项。Schedule
有关作业依赖项的更多一般信息,请参阅作业依赖项。