版本:2022.3
语言:英语
创建并运行工作流
并行工作流

工作流依赖性

通常,一个工作流依赖于另一个工作流的结果。例如,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();
    }

}

创建并运行工作流
并行工作流