Is Using of nativeArray have to use Complete in the mainThread?

I found that, if I use nativeArray, readonly or not, then I have to use Complete() in the main thread, or the editor would throw an exception:

" InvalidOperationException: The previously scheduled job DecisionSystem: ProcessTendency reads from the NativeArray ProcessTendency.Data.hasNavigationTags. You must call JobHandle.Complete() on the job DecisionSystem: ProcessTendency, before you can deallocate the NativeArray safely."

That’s fine but sounds a little bit less efficiency, because I have to wait every job to complete. What confused me is that why Boid Sample never called Complete()?

Hope anyone could help me, it confused me a few day…:stuck_out_tongue:

There are two potential problems underlying the issue and two ways to solve them.
1st scenario: You have 2 different systems updating the same NativeArray. In this case, you have to order those two systems to avoid the reader-write problem. Try labeling the latter system with UpdateAfter(typeof(FormerSystem))
2nd scenario: You have 1 system, within it multiple jobs, updating the same native array. To solve this, schedule the job that reads from the NativeArray with the JobHandle of the first job. Here’s an example:

var handle1 = new WriteJob{
     array = array
}.Schedule();
var handle2 = new ReadJob{
     array = array
}.Schedule(handle1);
1 Like

To add to @Abbrew 's 2nd point, if you have multiple writer jobs but know each value will only be written to by 1 Job (multiple values can be written to by the same job), then you can try [DisableNativeParallelForRestriction]

1 Like

To add to 1st scenario - update order alone may not be sufficient (in case the two systems don’t work on same component type, they will not register the dependency)

1 Like

@recursive @sngdan @Abbrew Thanks your guys! I didn’t explain very well I guess. Actually I do a few experiment, found that It has nothing to do with the Write problem. The problem I think is because before I even finished my job, the NativeArray is disposed (I disposed it manually at the end of OnUpdate).

What I found very handy is [DeallocateOnJobCompletion] attribute, after writing that on top of my nativeArray, I don’t need to either dispose it or call Complete().

Apologize for my poor english :stuck_out_tongue:

1 Like