What is GatherEntitiesJob and why is it failing on me when I use ToEntityArrayAsync

Hi there,
I try to use a NativeArray with entities inside my Entity.forEach. This is what I do. As you can see, I don’t even use the idleCharacterLst inside the foreach.

protected override void OnUpdate()
    {
        var idleCharacterLst = idleCharacterQuery.ToEntityArrayAsync(Allocator.TempJob, out var jobHandle1);


 Entities
  //         .WithDisposeOnCompletion(idleCharacterLst)
            .ForEach((Entity jobEntity, int entityInQueryIndex, ref JobData jobData) => {

            }).ScheduleParallel();

This is what I get:
InvalidOperationException: The previously scheduled job GatherEntitiesJob reads from the Unity.Entities.EntityTypeHandle GatherEntitiesJob.JobData.EntityTypeHandle. You must call JobHandle.Complete() on the job GatherEntitiesJob, before you can deallocate the Unity.Entities.EntityTypeHandle safely.

What does this mean… and how can I solve this?

cheers
Santo.

jobHandle1

you just have a hanging job handle. Your generating your idleCharacterLst asynchronously so you need to tell the job to wait on it by passing in the handle

Dependency = JobHandle.CombineDependencies(Dependency, jobHandle1);

Thanks for pointing that out, you are probably right about this. However, I simply reduced the code and commented out everything to figure out, what was causing the error. If I do this, I get the same error. (Maybe it’s still wrong, but should be correct in my understanding.

protected override void OnUpdate()
    {
        var idleCharacterLst = idleCharacterQuery.ToEntityArrayAsync(Allocator.TempJob, out var jobHandle1);
        Dependency = JobHandle.CombineDependencies(Dependency, jobHandle1);
Dependency = Entities
           .WithDisposeOnCompletion(idleCharacterLst)
            .ForEach((Entity jobEntity, int entityInQueryIndex, ref JobData jobData) => {
           
            for(int i=0; i<idleCharacterLst.size(); i++{
               //do stuff
            }
            }).ScheduleParallel(Dependency);
           
}

Thank you tertle for pointing out the correct problem. Next time I should post all of the code. :slight_smile:

I had this:

var idleCharacterLst = idleCharacterQuery.ToEntityArrayAsync(Allocator.TempJob, out var jobHandle1);
        if(idleCharacterLst.Length <= 0) {
            //leave if there is no idle character
            return;
        }
        Dependency = JobHandle.CombineDependencies(Dependency, jobHandle1);

       ....

But I need to do it like this, and now its working:

var idleCharacterLst = idleCharacterQuery.ToEntityArrayAsync(Allocator.TempJob, out var jobHandle1);
        Dependency = JobHandle.CombineDependencies(Dependency, jobHandle1);

        if(idleCharacterLst.Length <= 0) {
            idleCharacterLst.Dispose(Dependency);
            //leave if there is no idle character
            return;
        }