Weird error by just changing the entity count

I’m testing running IJobParallelFor jobs that hold a DynamicBuffer. This is related to my previous post , but now I found another error. Here’s the test code:

[AlwaysUpdateSystem]
public class DynamicBufferInIJobParallelFor : JobComponentSystem {
    // Just a tag for filtering
    private struct Filter : IComponentData {
    }

    private const int ENTITY_COUNT = 100;

    private EntityQuery query;

    private ArchetypeChunkBufferType<Int2BufferElement> bufferType;
   
    protected override void OnCreate() {
        // Create entities
        for (int i = 0; i < ENTITY_COUNT; ++i) {
            this.EntityManager.CreateEntity(typeof(Filter), typeof(Int2BufferElement));
        }

        this.query = GetEntityQuery(typeof(Filter), typeof(Int2BufferElement));
    }

    protected override JobHandle OnUpdate(JobHandle inputDeps) {
        this.bufferType = GetArchetypeChunkBufferType<Int2BufferElement>();

        JobHandle handle = inputDeps;
       
        NativeArray<ArchetypeChunk> chunks = this.query.CreateArchetypeChunkArray(Allocator.TempJob);
        for (int i = 0; i < chunks.Length; ++i) {
            handle = ProcessParallelFor(chunks[i], handle);
        }
        chunks.Dispose();
       
        return handle;
    }

    private JobHandle ProcessParallelFor(ArchetypeChunk chunk, JobHandle inputDeps) {
        BufferAccessor<Int2BufferElement> accessor = chunk.GetBufferAccessor(this.bufferType);
        JobParallelFor job = new JobParallelFor() {
            accessor = accessor
        };

        return job.Schedule(chunk.Count, 64, inputDeps);
    }

    [BurstCompile]
    private struct JobParallelFor : IJobParallelFor {
        [NativeDisableContainerSafetyRestriction]
        public BufferAccessor<Int2BufferElement> accessor;

        public void Execute(int index) {
            DynamicBuffer<Int2BufferElement> buffer = this.accessor[index];
            buffer.Clear();

            for (int i = 0; i < 1000; ++i) {
                buffer.Add(new Int2BufferElement() {
                    value = new int2(i, i)
                });
            }
        }
    }
}

Put this code into your project and run an empty scene. This system will still run. It will run fine without problems. Now change ENTITY_COUNT from 100 to 300. It produces the following error:

InvalidOperationException: The previously scheduled job DynamicBufferInIJobParallelFor:JobParallelFor writes to the NativeArray JobParallelFor.accessor. You must call JobHandle.Complete() on the job DynamicBufferInIJobParallelFor:JobParallelFor, before you can read from the NativeArray safely.

I think the error happens when there are more than one chunk. But each chunk is processed one by one by JobHandle chaining. How can this be fixed?

I was able to make it work by using BufferFromEntity instead:

private struct JobWithBufferFromEntity : IJobParallelFor {
    [ReadOnly]
    public NativeArray<Entity> entities;

    [NativeDisableContainerSafetyRestriction]
    public BufferFromEntity<Int2BufferElement> allBuffers;

    public void Execute(int index) {
        Entity entity = this.entities[index];
        DynamicBuffer<Int2BufferElement> buffer = this.allBuffers[entity];
       
        buffer.Clear();

        for (int i = 0; i < 1000; ++i) {
            buffer.Add(new Int2BufferElement() {
                value = new int2(i, i)
            });
        }
    }
}