Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

How to dispose NativeArray with ForEach lambda?

Discussion in 'Entity Component System' started by colin_young, Jan 14, 2020.

  1. colin_young

    colin_young

    Joined:
    Jun 1, 2017
    Posts:
    243
    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:

    Code (CSharp):
    1.             var laneExitBuffer = GetBufferFromEntity<LaneExitEntity>(true);
    2.  
    3.             NativeArray<Unity.Mathematics.Random> RandomGenerator = new NativeArray<Unity.Mathematics.Random>(JobsUtility.MaxJobThreadCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory);
    4.  
    5.             for (int i = 0; i < JobsUtility.MaxJobThreadCount; i++)
    6.             {
    7.                 RandomGenerator[i] = new Unity.Mathematics.Random((uint)randomSource.NextInt());
    8.             }
    9.  
    10.             var CommandBuffer = _entityCommandBufferSystem.CreateCommandBuffer().ToConcurrent();
    11.  
    12.             var job = Entities.WithAll<NeedsNextLaneTag, ERAutoTag>()
    13.                 .ForEach((Entity entity,
    14.                           int entityInQueryIndex,
    15.                           int nativeThreadIndex,
    16.                           ref VehicleLaneComponent vehicleLaneComponent) =>
    17.                 {
    18.                     // ... snip ...
    19.                 })
    20.                 .WithReadOnly(laneExitBuffer)
    21.                 .Schedule(inputDeps);
    22.  
    23.             _entityCommandBufferSystem.AddJobHandleForProducer(job);
    24.  
    25.             return job;
    26.  
    The offending collection is RandomGenerator. How do I properly dispose of that collection?
     
  2. 5argon

    5argon

    Joined:
    Jun 10, 2013
    Posts:
    1,554
    Put .WithDeallocateOnJobCompletion(RandomGenerator) to the ForEach then you can think there is an another job with dependency to that job that perform the Dispose.
     
    florianhanke likes this.
  3. colin_young

    colin_young

    Joined:
    Jun 1, 2017
    Posts:
    243
    Thanks! I was looking for something similar to that. Don't know how I missed it.
     
  4. elcionap

    elcionap

    Joined:
    Jan 11, 2016
    Posts:
    138
    You can also do this:
    Code (CSharp):
    1.  
    2. job = RandomGenerator.Dispose(job);
    3.  
    Also for the random generator you could use this:
    Code (CSharp):
    1.  
    2. inputDeps = Job
    3.     .WithCode(() => {
    4.         for (int i = 0; i < randomGenerator.Length; i++)
    5.         {
    6.             RandomGenerator[i] = new Unity.Mathematics.Random((uint)RandomSource.NextInt());
    7.         }
    8.     })
    9.     .Schedule(inputDeps);
    10.  
    []'s
     
    florianhanke likes this.