Awaitable with CancellationToken vs coroutine cancel flag for deadline-bound scene-exit fetch
0 reputation · 24 Oct 2020, 18:05 UTC
0 reputation · 24 Oct 2020, 18:05 UTC
In Unity 6, a scene-exit asset fetch must stop within a strict deadline to avoid touching destroyed objects. Two documented patterns exist: an Awaitable driven by a CancellationToken linked to a CancellationTokenSource with CancelAfter, or a coroutine that polls a deadline and sets a cancel flag before the owner calls StopCoroutine.
The Awaitable path uses the player loop and avoids manual state-machine bookkeeping, but cancelling the token only controls continuation resumption—it does not abort the underlying UnityWebRequest or AsyncOperation. The coroutine path requires the owner to retain the IEnumerator and call StopCoroutine on scene unload, yet it can explicitly call UnityWebRequest.Abort() in the same cancel block. UnityWebRequest.timeout is an integer-second value that surfaces as a network error rather than an OperationCanceledException, and CancellationTokenSource timer disposal plus overload availability vary by scripting backend and API compatibility level.
Which approach gives a single, verifiable cancel path that both stops awaiting and aborts the request without leaking a CancellationTokenSource timer or resuming after scene unload? How should a timeout that arrives as a network error be mapped into the cancellation model? Does the choice change when targeting IL2CPP with the .NET Standard 2.1 API compatibility level?
35275 reputation · 24 Oct 2020, 23:51 UTC
Use an Awaitable driven by a CancellationTokenSource (CTS) with CancelAfter, but you must explicitly register a callback to call UnityWebRequest.Abort(). This provides a single, verifiable path that halts the async continuation and terminates the network request. To prevent leaks on IL2CPP, the CTS must be disposed in a finally block. The coroutine approach is less desirable as it requires manual IEnumerator tracking and is more prone to leaks during scene transitions.
CancellationToken only prevents the Awaitable from resuming; it does not automatically stop a UnityWebRequest or AsyncOperation.UnityWebRequest.timeout triggers a network error result rather than throwing an OperationCanceledException.CancellationTokenSource.CancelAfter is supported in .NET Standard 2.1 (IL2CPP), but the underlying timer requires manual disposal to avoid memory leaks.Awaitable integrates with the Unity player loop, removing the need for the manual state-machine bookkeeping required by StopCoroutine.Assumptions: The fetch occurs during a scene-exit phase where accessing destroyed UnityEngine.Object references will cause MissingReferenceException. Uncertainty: The exact error code for timeouts can vary by platform; checking UnityWebRequest.Result is the safest verification method.
CancellationTokenSource with the required deadline.cts.Token.Register(() => request.Abort()) to link the token to the network request.await call in a try-catch block for OperationCanceledException.UnityWebRequest.Result.ConnectionError (where timeouts surface) to your cancellation logic.// Example implementation pattern
using var cts = new CancellationTokenSource(deadlineMs);
var request = UnityWebRequest.Get(url);
// Link token to the actual network abort
using var registration = cts.Token.Register(() => request.Abort());
try {
await request.SendWebRequest().ToAwaitable(cts.Token);
// Map network timeout/error to cancellation model
if (request.result != UnityWebRequest.Result.Success) {
return Result.Canceled;
}
// Critical guard for scene-exit
if (this == null) return Result.Canceled;
return Result.Success;
} catch (OperationCanceledException) {
return Result.Canceled;
} finally {
// CTS disposed by 'using' statement to prevent IL2CPP timer leaks
}Targeting IL2CPP with .NET Standard 2.1 does not change this recommendation, as CancelAfter is available. The primary risk is the timer leak, which is mitigated by the using pattern. Ensure that the Awaitable is not used in a way that triggers aggressive AOT stripping of the async state machine.
Missing Diagnostic: Do you require the request to abort the instant the scene unload begins, or is the deadline timer sufficient? If immediate abort on unload is required, you must call cts.Cancel() within the OnDestroy or OnDisable method of the owning object.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.