Search Issue Tracker

By Design

Votes

3

Found in

2021.3.40f1

2022.3.38f1

6000.0.11f1

6000.1.0a7

6000.2.0a1

6000.3.0a1

6000.4.0a1

6000.5.0a1

Issue ID

UUM-76308

Regression

No

NativeArray with Allocator.Temp is disposed when used with Async/Await

Kernel (DOTS)

-

Steps to reproduce:
1. Create a new project
2. Download and import the attached script "TempAllocatorAccess.cs"
3. Assign the script to a new GameObject
4. Enter Play Mode
5. Observe the console error "ObjectDisposedException: Cannot access a disposed object."

Expected Results: NativeArray with Allocator.Temp is not disposed when used with Async/Await
Actual Results: NativeArray with Allocator.Temp is disposed when used with Async/Await

Reproducible on: 2021.3.40f1, 2022.3.38f1, 6000.0.11f1

Testing Environment: Windows 11
Not reproducible on: No other environment tested

Notes:
-Full console errors:
Error accessing collection after awaiting: The Unity.Collections.NativeArray`1[System.Int32] has been deallocated, it is not allowed to access it
UnityEngine.Debug:LogError (object)
TempCollectionAccess/<Initialize>d__0:MoveNext () (at Assets/TempCollectionAccess.cs:33)
UnityEngine.UnitySynchronizationContext:ExecuteTasks ()
-
ObjectDisposedException: Cannot access a disposed object.
Object name: 'The NativeArray has been disposed, it is not allowed to access it'.
Unity.Collections.NativeArray`1[T].Dispose () (at <2d8783c7af0442318483a199a473c55b>:0)
TempCollectionAccess.Initialize () (at Assets/TempCollectionAccess.cs:37)
System.Runtime.CompilerServices.AsyncMethodBuilderCore+<>c.<ThrowAsync>b__7_0 (System.Object state) (at <c0b7b90d34a54066a7234dad69255116>:0)
UnityEngine.UnitySynchronizationContext+WorkRequest.Invoke () (at <2d8783c7af0442318483a199a473c55b>:0)
UnityEngine.UnitySynchronizationContext.Exec () (at <2d8783c7af0442318483a199a473c55b>:0)
UnityEngine.UnitySynchronizationContext.ExecuteTasks () (at <2d8783c7af0442318483a199a473c55b>:0)

  1. Resolution Note:

    Thank you for submitting a bug report. This case is being closed as 'As Designed.' for the following reason:

    "Allocator.Temp" [documentation|https://docs.unity3d.com/Packages/com.unity.collections@2.6/manual/allocator-overview.html#allocatortemp] cites its lifetime in the context of a single frame.  In the attached script, "await Task.Delay" is used to wait one second, from which the frame that the native array was created under will have already ended/it will have been disposed.  Changing the "Time.Delay()" call in the sample script to take in "TimeSpan.FromTicks()" calls with small values like 100, the native array is still accessible when entering Play mode with the script attached to a game object.  The same "ObjectDisposedException" is thrown with larger tick values, since the initial frame is no longer the current one.

    The expectation may be that that since we have not gone out of scope, the container should still exist, since the documentation states, "Temp allocations are only safe to use in the thread and the scope where they were allocated.".  However, the "await" splits execution into separate segments, to which time and frame boundaries may have shifted when execution resumes in the method resumes.

    If you need an object to persist over multiple frames, a [persistent allocator|https://docs.unity3d.com/Packages/com.unity.collections@2.6/manual/allocator-overview.html#allocatorpersistent] can be used with an explicit disposal of the object when you are done with it.  Alternatively, a job allocator could be used if the container has less than or equal to 4 frames of lifetime.  It will also need to be explicitly disposed.

  2. Resolution Note:

    Thank you for submitting a bug report. This case is being closed as 'As Designed.' for the following reason:

    "Allocator.Temp" [documentation|https://docs.unity3d.com/Packages/com.unity.collections@2.6/manual/allocator-overview.html#allocatortemp] cites its lifetime in the context of a single frame.  In the attached script, "await Task.Delay" is used to wait one second, from which the frame that the native array was created under will have already ended/it will have been disposed.  Changing the "Time.Delay()" call in the sample script to take in "TimeSpan.FromTicks()" calls with small values like 100, the native array is still accessible when entering Play mode with the script attached to a game object.  The same "ObjectDisposedException" is thrown with larger tick values, since the initial frame is no longer the current one.

    The expectation may be that that since we have not gone out of scope, the container should still exist, since the documentation states, "Temp allocations are only safe to use in the thread and the scope where they were allocated.".  However, the "await" splits execution into separate segments, to which time and frame boundaries may have shifted when execution resumes in the method resumes.

    If you need an object to persist over multiple frames, a [persistent allocator|https://docs.unity3d.com/Packages/com.unity.collections@2.6/manual/allocator-overview.html#allocatorpersistent] can be used with an explicit disposal of the object when you are done with it.  Alternatively, a job allocator could be used if the container has less than or equal to 4 frames of lifetime.  It will also need to be explicitly disposed.

Add comment

Log in to post comment

All about bugs

View bugs we have successfully reproduced, and vote for the bugs you want to see fixed most urgently.