通常,一个工作流依赖于另一个工作流的结果。例如,Job A 可能会向 job B 作为输入使用的 NativeArray 写入。当你安排一个相关的工作流时,必须通知工作流系统这种依赖关系。在工作流完成它所依赖的工作之前,工作流系统不会运行相关的工作流。一个工作流可以依赖于多个工作流。
你还可以有一系列的工作流,其中每个工作流都依赖于前面一个。然而,由于你必须等待工作流的任何依赖关系完成才能运行,依赖关系会延迟工作流的执行。完成相关的工作流必须首先完成它所依赖的工作,以及任何那些工作所依赖的工作。
当你调用工作流的 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);
以下是一个多个工作流和多个依赖关系的示例。最佳实践是将工作流代码(《MyJob》和《AddOneJob》)放在与《Update》和《LateUpdate》代码不同的文件中,但为了清晰起见,此示例在一个文件中
using UnityEngine;
using Unity.Collections;
using Unity.Jobs;
public class MyDependentJob : MonoBehaviour
{
// Create a native array of a single float to store the result. This example waits for the job to complete.
NativeArray<float> result;
// Create a JobHandle to access the results
JobHandle secondHandle;
// Set up the first job
public struct MyJob : IJob
{
public float a;
public float b;
public NativeArray<float> result;
public void Execute()
{
result[0] = a + b;
}
}
// Set up the second job, which adds one to a value
public struct AddOneJob : IJob
{
public NativeArray<float> result;
public void Execute()
{
result[0] = result[0] + 1;
}
}
// Update is called once per frame
void Update()
{
// Set up the job data for the first job
result = new NativeArray<float>(1, Allocator.TempJob);
MyJob jobData = new MyJob
{
a = 10,
b = 10,
result = result
};
// Schedule the first job
JobHandle firstHandle = jobData.Schedule();
// Setup the data for the second job
AddOneJob incJobData = new AddOneJob
{
result = result
};
// Schedule the second job
secondHandle = incJobData.Schedule(firstHandle);
}
private void LateUpdate()
{
// Sometime later in the frame, wait for the job to complete before accessing the results.
secondHandle.Complete();
// All copies of the NativeArray point to the same memory, you can access the result in "your" copy of the NativeArray
// float aPlusBPlusOne = result[0];
// Free the memory allocated by the result array
result.Dispose();
}
}