JobHandle和依赖项
要当您调用作业的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);
// Populate `handles` with `JobHandles` from multiple scheduled jobs...
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方法
。两者在调用Complete方法后都能安全访问主线程得到NativeContainer类型的结果。
否则,如果您不需要访问数据,则需要明确刷新批处理。为此,请调用静态方法JobHandle.ScheduleBatchedJobs。请注意,调用此方法会对性能产生负面影响。
多个作业和依赖项的示例
工作代码:
// Job adding two floating point values together
public struct MyJob : IJob
{
public float a;
public float b;
public NativeArray<float> result;
public void Execute()
{
result[0] = a + b;
}
}
// Job adding one to a value
public struct AddOneJob : IJob
{
public NativeArray<float> result;
public void Execute()
{
result[0] = result[0] + 1;
}
}
主线程代码:
// Create a native array of a single float to store the result in. This example waits for the job to complete
NativeArray<float> result = new NativeArray<float>(1, Allocator.TempJob);
// Setup the data for job #1
MyJob jobData = new MyJob();
jobData.a = 10;
jobData.b = 10;
jobData.result = result;
// Schedule job #1
JobHandle firstHandle = jobData.Schedule();
// Setup the data for job #2
AddOneJob incJobData = new AddOneJob();
incJobData.result = result;
// Schedule job #2
JobHandle secondHandle = incJobData.Schedule(firstHandle);
// Wait for job #2 to complete
secondHandle.Complete();
// All copies of the NativeArray point to the same memory, you can access the result in "your" copy of the NativeArray
float aPlusB = result[0];
// Free the memory allocated by the result array
result.Dispose();