How to dispose NativeArray with ForEach lambda?

I recently converted one of my jobs to use the ForEach style instead of the IJobForEachWithEntity struct style. After converting I started to see “A Native Collection has not been disposed” exceptions. Mostly, I suspect because previously I was able to mark the collections for disposal after the job completes with the DeallocateOnJobCompletion attribute. This is what my code looks like:

            var laneExitBuffer = GetBufferFromEntity<LaneExitEntity>(true);

            NativeArray<Unity.Mathematics.Random> RandomGenerator = new NativeArray<Unity.Mathematics.Random>(JobsUtility.MaxJobThreadCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory);

            for (int i = 0; i < JobsUtility.MaxJobThreadCount; i++)
            {
                RandomGenerator[i] = new Unity.Mathematics.Random((uint)randomSource.NextInt());
            }

            var CommandBuffer = _entityCommandBufferSystem.CreateCommandBuffer().ToConcurrent();

            var job = Entities.WithAll<NeedsNextLaneTag, ERAutoTag>()
                .ForEach((Entity entity,
                          int entityInQueryIndex,
                          int nativeThreadIndex,
                          ref VehicleLaneComponent vehicleLaneComponent) =>
                {
                    // ... snip ...
                })
                .WithReadOnly(laneExitBuffer)
                .Schedule(inputDeps);

            _entityCommandBufferSystem.AddJobHandleForProducer(job);

            return job;

The offending collection is RandomGenerator. How do I properly dispose of that collection?

Put .WithDeallocateOnJobCompletion(RandomGenerator) to the ForEach then you can think there is an another job with dependency to that job that perform the Dispose.

1 Like

Thanks! I was looking for something similar to that. Don’t know how I missed it.

You can also do this:

job = RandomGenerator.Dispose(job);

Also for the random generator you could use this:

inputDeps = Job
    .WithCode(() => {
        for (int i = 0; i < randomGenerator.Length; i++)
        {
            RandomGenerator[i] = new Unity.Mathematics.Random((uint)RandomSource.NextInt());
        }
    })
    .Schedule(inputDeps);

[ ]'s

1 Like