Quick answer: Call handle.Complete() before Dispose()-ing any NativeArray the job uses. Or attach [DeallocateOnJobCompletion] so the job frees it safely on finish.

A Burst job runs over a NativeArray. The next line disposes the array — and the safety system throws “The NativeArray has been disposed” because the job is still reading it.

Complete, Then Dispose

var data = new NativeArray<float>(count, Allocator.TempJob);
var handle = job.Schedule(count, 64);

handle.Complete();   // wait for the job to finish using `data`
// ... read results ...
data.Dispose();

The job runs asynchronously. Disposing before Complete frees memory the job still touches — a real race the safety system catches in the editor.

Auto-Deallocate Option

[BurstCompile]
struct MyJob : IJobParallelFor
{
    [DeallocateOnJobCompletion]
    public NativeArray<float> ScratchData;
    public void Execute(int i) { ... }
}

For scratch arrays you don’t need after the job, [DeallocateOnJobCompletion] frees them when the job finishes — no manual Dispose, no race.

Allocator Choice

Allocator.TempJob is for arrays that live for a few frames at most — the safety system warns if you hold one too long. Allocator.Persistent for long-lived; you must Dispose it yourself (after Complete).

Verifying

No “disposed” or “deallocated” errors. The Jobs Debugger shows the handle completed before the dispose. Results read correctly.

“Complete the job, then dispose its arrays. Or let [DeallocateOnJobCompletion] do it.”

Keep the safety system on in dev — it turns these races into immediate, clear errors instead of mysterious crashes in release.