调用作业的 Schedule 方法时,将返回 JobHandle。可以在代码中使用 JobHandle
作为其他作业的依赖项。如果一个作业依赖于另一个作业的结果,则可以将第一个作业的 JobHandle
作为参数传递给第二个作业的 Schedule
方法,如下所示:
JobHandle firstJobHandle = firstJob.Schedule();
secondJob.Schedule(firstJobHandle);
如果一个作业具有许多依赖项,则可以使用 JobHandle.CombineDependencies 方法合并这些依赖项。CombineDependencies
可以将依赖项传递给 Schedule
方法。
NativeArray<JobHandle> handles = new NativeArray<JobHandle>(numJobs, Allocator.TempJob);
// 使用来自多个调度作业的 `JobHandles` 填充 `handles`...
JobHandle jh = JobHandle.CombineDependencies(handles);
使用 JobHandle
可以强制代码在主线程中等待作业完成执行。为此,请在 JobHandle
上调用 Complete 方法。此时,您知道主线程可以安全地访问作业所使用的 NativeContainer。
注意:在调度作业时,作业不会开始执行。如果您正在主线程中等待作业,并需要访问作业所使用的 NativeContainer 数据,则可以调用 JobHandle.Complete
方法。此方法会在内存缓存中刷新作业并启动执行过程。在 JobHandle
上调用 Complete
会将该作业的 NativeContainer
类型的所有权交还给主线程。您需要在 JobHandle
上调用 Complete
才能再次从主线程中安全地访问这些 NativeContainer
类型。此外,也可以通过在作业依赖关系中的 JobHandle
上调用 Complete
来将所有权交还给主线程。例如,可以在 jobA
上调用 Complete
,也可以在依赖于 jobA
的 jobB
上调用 Complete
。两种方式都会使 jobA
使用的 NativeContainer
类型在调用 Complete
之后可以在主线程上安全地访问。
否则,如果您不需要访问数据,则需要显式刷新批次。为此,请调用静态方法 JobHandle.ScheduleBatchedJobs。请注意,调用此方法会对性能产生负面影响。
作业代码:
// 将两个浮点值相加的作业
public struct MyJob : IJob
{
public float a;
public float b;
public NativeArray<float> result;
public void Execute()
{
result[0] = a + b;
}
}
// 将一个值加一的作业
public struct AddOneJob : IJob
{
public NativeArray<float> result;
public void Execute()
{
result[0] = result[0] + 1;
}
}
主线程代码:
// 创建单个浮点数的本机数组以存储结果。此示例等待作业完成
NativeArray<float> result = new NativeArray<float>(1, Allocator.TempJob);
// 设置作业 #1 的数据
MyJob jobData = new MyJob();
jobData.a = 10;
jobData.b = 10;
jobData.result = result;
// 调度作业 #1
JobHandle firstHandle = jobData.Schedule();
// 设置作业 #2 的数据
AddOneJob incJobData = new AddOneJob();
incJobData.result = result;
// 调度作业 #2
JobHandle secondHandle = incJobData.Schedule(firstHandle);
// 等待作业 #2 完成
secondHandle.Complete();
// NativeArray 的所有副本都指向同一内存,您可以在"您的"NativeArray 副本中访问结果
float aPlusB = result[0];
// 释放由结果数组分配的内存
result.Dispose();