diff --git a/src/UniTask/Assets/Plugins/UniTask/Runtime/External/Addressables/AddressablesAsyncExtensions.cs b/src/UniTask/Assets/Plugins/UniTask/Runtime/External/Addressables/AddressablesAsyncExtensions.cs index 620cfadc..ee1a9e6c 100644 --- a/src/UniTask/Assets/Plugins/UniTask/Runtime/External/Addressables/AddressablesAsyncExtensions.cs +++ b/src/UniTask/Assets/Plugins/UniTask/Runtime/External/Addressables/AddressablesAsyncExtensions.cs @@ -110,6 +110,7 @@ static AsyncOperationHandleConfiguredSource() CancellationTokenRegistration cancellationTokenRegistration; IProgress progress; bool autoReleaseWhenCanceled; + bool cancelImmediately; bool completed; UniTaskCompletionSourceCore core; @@ -134,8 +135,9 @@ public static IUniTaskSource Create(AsyncOperationHandle handle, PlayerLoopTimin result.handle = handle; result.progress = progress; result.cancellationToken = cancellationToken; - result.completed = false; + result.cancelImmediately = cancelImmediately; result.autoReleaseWhenCanceled = autoReleaseWhenCanceled; + result.completed = false; if (cancelImmediately && cancellationToken.CanBeCanceled) { @@ -169,33 +171,41 @@ void HandleCompleted(AsyncOperationHandle _) if (completed) { - TryReturn(); + return; } - else + + completed = true; + if (cancellationToken.IsCancellationRequested) { - completed = true; - if (cancellationToken.IsCancellationRequested) - { - if (autoReleaseWhenCanceled && handle.IsValid()) - { - Addressables.Release(handle); - } - core.TrySetCanceled(cancellationToken); - } - else if (handle.Status == AsyncOperationStatus.Failed) - { - core.TrySetException(handle.OperationException); - } - else + if (autoReleaseWhenCanceled && handle.IsValid()) { - core.TrySetResult(AsyncUnit.Default); + Addressables.Release(handle); } + core.TrySetCanceled(cancellationToken); + } + else if (handle.Status == AsyncOperationStatus.Failed) + { + core.TrySetException(handle.OperationException); + } + else + { + core.TrySetResult(AsyncUnit.Default); } } public void GetResult(short token) { - core.GetResult(token); + try + { + core.GetResult(token); + } + finally + { + if (!(cancelImmediately && cancellationToken.IsCancellationRequested)) + { + TryReturn(); + } + } } public UniTaskStatus GetStatus(short token) @@ -217,7 +227,6 @@ public bool MoveNext() { if (completed) { - TryReturn(); return false; } @@ -304,6 +313,7 @@ static AsyncOperationHandleConfiguredSource() CancellationTokenRegistration cancellationTokenRegistration; IProgress progress; bool autoReleaseWhenCanceled; + bool cancelImmediately; bool completed; UniTaskCompletionSourceCore core; @@ -330,6 +340,7 @@ public static IUniTaskSource Create(AsyncOperationHandle handle, PlayerLoo result.completed = false; result.progress = progress; result.autoReleaseWhenCanceled = autoReleaseWhenCanceled; + result.cancelImmediately = cancelImmediately; if (cancelImmediately && cancellationToken.CanBeCanceled) { @@ -363,33 +374,38 @@ void HandleCompleted(AsyncOperationHandle argHandle) if (completed) { - TryReturn(); + return; } - else + completed = true; + if (cancellationToken.IsCancellationRequested) { - completed = true; - if (cancellationToken.IsCancellationRequested) - { - if (autoReleaseWhenCanceled && handle.IsValid()) - { - Addressables.Release(handle); - } - core.TrySetCanceled(cancellationToken); - } - else if (argHandle.Status == AsyncOperationStatus.Failed) - { - core.TrySetException(argHandle.OperationException); - } - else + if (autoReleaseWhenCanceled && handle.IsValid()) { - core.TrySetResult(argHandle.Result); + Addressables.Release(handle); } + core.TrySetCanceled(cancellationToken); + } + else if (argHandle.Status == AsyncOperationStatus.Failed) + { + core.TrySetException(argHandle.OperationException); + } + else + { + core.TrySetResult(argHandle.Result); } } public T GetResult(short token) { - return core.GetResult(token); + try + { + return core.GetResult(token); + } + finally + { + if (!(cancelImmediately && cancellationToken.IsCancellationRequested)) + TryReturn(); + } } void IUniTaskSource.GetResult(short token) @@ -416,7 +432,6 @@ public bool MoveNext() { if (completed) { - TryReturn(); return false; } diff --git a/src/UniTask/Assets/Plugins/UniTask/Runtime/UniTask.Delay.cs b/src/UniTask/Assets/Plugins/UniTask/Runtime/UniTask.Delay.cs index 7f02a1a1..8ac8a29b 100644 --- a/src/UniTask/Assets/Plugins/UniTask/Runtime/UniTask.Delay.cs +++ b/src/UniTask/Assets/Plugins/UniTask/Runtime/UniTask.Delay.cs @@ -208,6 +208,7 @@ static YieldPromise() CancellationToken cancellationToken; CancellationTokenRegistration cancellationTokenRegistration; + bool cancelImmediately; UniTaskCompletionSourceCore core; YieldPromise() @@ -227,6 +228,7 @@ public static IUniTaskSource Create(PlayerLoopTiming timing, CancellationToken c } result.cancellationToken = cancellationToken; + result.cancelImmediately = cancelImmediately; if (cancelImmediately && cancellationToken.CanBeCanceled) { @@ -253,7 +255,10 @@ public void GetResult(short token) } finally { - TryReturn(); + if (!(cancelImmediately && cancellationToken.IsCancellationRequested)) + { + TryReturn(); + } } } @@ -290,6 +295,7 @@ bool TryReturn() core.Reset(); cancellationToken = default; cancellationTokenRegistration.Dispose(); + cancelImmediately = default; return pool.TryPush(this); } } @@ -309,6 +315,7 @@ static NextFramePromise() UniTaskCompletionSourceCore core; CancellationToken cancellationToken; CancellationTokenRegistration cancellationTokenRegistration; + bool cancelImmediately; NextFramePromise() { @@ -328,6 +335,7 @@ public static IUniTaskSource Create(PlayerLoopTiming timing, CancellationToken c result.frameCount = PlayerLoopHelper.IsMainThread ? Time.frameCount : -1; result.cancellationToken = cancellationToken; + result.cancelImmediately = cancelImmediately; if (cancelImmediately && cancellationToken.CanBeCanceled) { @@ -354,7 +362,10 @@ public void GetResult(short token) } finally { - TryReturn(); + if (!(cancelImmediately && cancellationToken.IsCancellationRequested)) + { + TryReturn(); + } } } @@ -414,6 +425,7 @@ static WaitForEndOfFramePromise() UniTaskCompletionSourceCore core; CancellationToken cancellationToken; CancellationTokenRegistration cancellationTokenRegistration; + bool cancelImmediately; WaitForEndOfFramePromise() { @@ -432,6 +444,7 @@ public static IUniTaskSource Create(MonoBehaviour coroutineRunner, CancellationT } result.cancellationToken = cancellationToken; + result.cancelImmediately = cancelImmediately; if (cancelImmediately && cancellationToken.CanBeCanceled) { @@ -458,7 +471,10 @@ public void GetResult(short token) } finally { - TryReturn(); + if (!(cancelImmediately && cancellationToken.IsCancellationRequested)) + { + TryReturn(); + } } } @@ -533,6 +549,7 @@ static DelayFramePromise() int delayFrameCount; CancellationToken cancellationToken; CancellationTokenRegistration cancellationTokenRegistration; + bool cancelImmediately; int currentFrameCount; UniTaskCompletionSourceCore core; @@ -556,6 +573,7 @@ public static IUniTaskSource Create(int delayFrameCount, PlayerLoopTiming timing result.delayFrameCount = delayFrameCount; result.cancellationToken = cancellationToken; result.initialFrame = PlayerLoopHelper.IsMainThread ? Time.frameCount : -1; + result.cancelImmediately = cancelImmediately; if (cancelImmediately && cancellationToken.CanBeCanceled) { @@ -582,7 +600,10 @@ public void GetResult(short token) } finally { - TryReturn(); + if (!(cancelImmediately && cancellationToken.IsCancellationRequested)) + { + TryReturn(); + } } } @@ -653,6 +674,7 @@ bool TryReturn() delayFrameCount = default; cancellationToken = default; cancellationTokenRegistration.Dispose(); + cancelImmediately = default; return pool.TryPush(this); } } @@ -673,6 +695,7 @@ static DelayPromise() float elapsed; CancellationToken cancellationToken; CancellationTokenRegistration cancellationTokenRegistration; + bool cancelImmediately; UniTaskCompletionSourceCore core; @@ -696,6 +719,7 @@ public static IUniTaskSource Create(TimeSpan delayTimeSpan, PlayerLoopTiming tim result.delayTimeSpan = (float)delayTimeSpan.TotalSeconds; result.cancellationToken = cancellationToken; result.initialFrame = PlayerLoopHelper.IsMainThread ? Time.frameCount : -1; + result.cancelImmediately = cancelImmediately; if (cancelImmediately && cancellationToken.CanBeCanceled) { @@ -722,7 +746,10 @@ public void GetResult(short token) } finally { - TryReturn(); + if (!(cancelImmediately && cancellationToken.IsCancellationRequested)) + { + TryReturn(); + } } } @@ -775,6 +802,7 @@ bool TryReturn() elapsed = default; cancellationToken = default; cancellationTokenRegistration.Dispose(); + cancelImmediately = default; return pool.TryPush(this); } } @@ -795,6 +823,7 @@ static DelayIgnoreTimeScalePromise() int initialFrame; CancellationToken cancellationToken; CancellationTokenRegistration cancellationTokenRegistration; + bool cancelImmediately; UniTaskCompletionSourceCore core; @@ -818,6 +847,7 @@ public static IUniTaskSource Create(TimeSpan delayFrameTimeSpan, PlayerLoopTimin result.delayFrameTimeSpan = (float)delayFrameTimeSpan.TotalSeconds; result.initialFrame = PlayerLoopHelper.IsMainThread ? Time.frameCount : -1; result.cancellationToken = cancellationToken; + result.cancelImmediately = cancelImmediately; if (cancelImmediately && cancellationToken.CanBeCanceled) { @@ -844,7 +874,10 @@ public void GetResult(short token) } finally { - TryReturn(); + if (!(cancelImmediately && cancellationToken.IsCancellationRequested)) + { + TryReturn(); + } } } @@ -897,6 +930,7 @@ bool TryReturn() elapsed = default; cancellationToken = default; cancellationTokenRegistration.Dispose(); + cancelImmediately = default; return pool.TryPush(this); } } @@ -916,6 +950,7 @@ static DelayRealtimePromise() ValueStopwatch stopwatch; CancellationToken cancellationToken; CancellationTokenRegistration cancellationTokenRegistration; + bool cancelImmediately; UniTaskCompletionSourceCore core; @@ -938,6 +973,7 @@ public static IUniTaskSource Create(TimeSpan delayTimeSpan, PlayerLoopTiming tim result.stopwatch = ValueStopwatch.StartNew(); result.delayTimeSpanTicks = delayTimeSpan.Ticks; result.cancellationToken = cancellationToken; + result.cancelImmediately = cancelImmediately; if (cancelImmediately && cancellationToken.CanBeCanceled) { @@ -964,7 +1000,10 @@ public void GetResult(short token) } finally { - TryReturn(); + if (!(cancelImmediately && cancellationToken.IsCancellationRequested)) + { + TryReturn(); + } } } @@ -1013,6 +1052,7 @@ bool TryReturn() stopwatch = default; cancellationToken = default; cancellationTokenRegistration.Dispose(); + cancelImmediately = default; return pool.TryPush(this); } } diff --git a/src/UniTask/Assets/Plugins/UniTask/Runtime/UniTask.WaitUntil.cs b/src/UniTask/Assets/Plugins/UniTask/Runtime/UniTask.WaitUntil.cs index b28a529e..d126199e 100644 --- a/src/UniTask/Assets/Plugins/UniTask/Runtime/UniTask.WaitUntil.cs +++ b/src/UniTask/Assets/Plugins/UniTask/Runtime/UniTask.WaitUntil.cs @@ -49,6 +49,7 @@ static WaitUntilPromise() Func predicate; CancellationToken cancellationToken; CancellationTokenRegistration cancellationTokenRegistration; + bool cancelImmediately; UniTaskCompletionSourceCore core; @@ -70,6 +71,7 @@ public static IUniTaskSource Create(Func predicate, PlayerLoopTiming timin result.predicate = predicate; result.cancellationToken = cancellationToken; + result.cancelImmediately = cancelImmediately; if (cancelImmediately && cancellationToken.CanBeCanceled) { @@ -96,7 +98,10 @@ public void GetResult(short token) } finally { - TryReturn(); + if (!(cancelImmediately && cancellationToken.IsCancellationRequested)) + { + TryReturn(); + } } } @@ -147,6 +152,7 @@ bool TryReturn() predicate = default; cancellationToken = default; cancellationTokenRegistration.Dispose(); + cancelImmediately = default; return pool.TryPush(this); } } @@ -165,6 +171,7 @@ static WaitWhilePromise() Func predicate; CancellationToken cancellationToken; CancellationTokenRegistration cancellationTokenRegistration; + bool cancelImmediately; UniTaskCompletionSourceCore core; @@ -212,7 +219,10 @@ public void GetResult(short token) } finally { - TryReturn(); + if (!(cancelImmediately && cancellationToken.IsCancellationRequested)) + { + TryReturn(); + } } } @@ -263,6 +273,7 @@ bool TryReturn() predicate = default; cancellationToken = default; cancellationTokenRegistration.Dispose(); + cancelImmediately = default; return pool.TryPush(this); } } @@ -280,6 +291,7 @@ static WaitUntilCanceledPromise() CancellationToken cancellationToken; CancellationTokenRegistration cancellationTokenRegistration; + bool cancelImmediately; UniTaskCompletionSourceCore core; @@ -287,7 +299,7 @@ static WaitUntilCanceledPromise() { } - public static IUniTaskSource Create(CancellationToken cancellationToken, PlayerLoopTiming timing, bool completeImmediately, out short token) + public static IUniTaskSource Create(CancellationToken cancellationToken, PlayerLoopTiming timing, bool cancelImmediately, out short token) { if (cancellationToken.IsCancellationRequested) { @@ -300,8 +312,9 @@ public static IUniTaskSource Create(CancellationToken cancellationToken, PlayerL } result.cancellationToken = cancellationToken; + result.cancelImmediately = cancelImmediately; - if (completeImmediately && cancellationToken.CanBeCanceled) + if (cancelImmediately && cancellationToken.CanBeCanceled) { result.cancellationTokenRegistration = cancellationToken.RegisterWithoutCaptureExecutionContext(state => { @@ -326,7 +339,10 @@ public void GetResult(short token) } finally { - TryReturn(); + if (!(cancelImmediately && cancellationToken.IsCancellationRequested)) + { + TryReturn(); + } } } @@ -362,6 +378,7 @@ bool TryReturn() core.Reset(); cancellationToken = default; cancellationTokenRegistration.Dispose(); + cancelImmediately = default; return pool.TryPush(this); } } @@ -385,6 +402,7 @@ static WaitUntilValueChangedUnityObjectPromise() IEqualityComparer equalityComparer; CancellationToken cancellationToken; CancellationTokenRegistration cancellationTokenRegistration; + bool cancelImmediately; UniTaskCompletionSourceCore core; @@ -410,6 +428,7 @@ public static IUniTaskSource Create(T target, Func monitorFunction, IEq result.currentValue = monitorFunction(target); result.equalityComparer = equalityComparer ?? UnityEqualityComparer.GetDefault(); result.cancellationToken = cancellationToken; + result.cancelImmediately = cancelImmediately; if (cancelImmediately && cancellationToken.CanBeCanceled) { @@ -436,7 +455,10 @@ public U GetResult(short token) } finally { - TryReturn(); + if (!(cancelImmediately && cancellationToken.IsCancellationRequested)) + { + TryReturn(); + } } } @@ -497,6 +519,7 @@ bool TryReturn() equalityComparer = default; cancellationToken = default; cancellationTokenRegistration.Dispose(); + cancelImmediately = default; return pool.TryPush(this); } } @@ -519,6 +542,7 @@ static WaitUntilValueChangedStandardObjectPromise() IEqualityComparer equalityComparer; CancellationToken cancellationToken; CancellationTokenRegistration cancellationTokenRegistration; + bool cancelImmediately; UniTaskCompletionSourceCore core; @@ -543,6 +567,7 @@ public static IUniTaskSource Create(T target, Func monitorFunction, IEq result.currentValue = monitorFunction(target); result.equalityComparer = equalityComparer ?? UnityEqualityComparer.GetDefault(); result.cancellationToken = cancellationToken; + result.cancelImmediately = cancelImmediately; if (cancelImmediately && cancellationToken.CanBeCanceled) { @@ -569,7 +594,10 @@ public U GetResult(short token) } finally { - TryReturn(); + if (!(cancelImmediately && cancellationToken.IsCancellationRequested)) + { + TryReturn(); + } } } @@ -630,6 +658,7 @@ bool TryReturn() equalityComparer = default; cancellationToken = default; cancellationTokenRegistration.Dispose(); + cancelImmediately = default; return pool.TryPush(this); } } diff --git a/src/UniTask/Assets/Plugins/UniTask/Runtime/UnityAsyncExtensions.AssetBundleRequestAllAssets.cs b/src/UniTask/Assets/Plugins/UniTask/Runtime/UnityAsyncExtensions.AssetBundleRequestAllAssets.cs index 5d34692d..043e1b8b 100644 --- a/src/UniTask/Assets/Plugins/UniTask/Runtime/UnityAsyncExtensions.AssetBundleRequestAllAssets.cs +++ b/src/UniTask/Assets/Plugins/UniTask/Runtime/UnityAsyncExtensions.AssetBundleRequestAllAssets.cs @@ -101,6 +101,7 @@ static AssetBundleRequestAllAssetsConfiguredSource() IProgress progress; CancellationToken cancellationToken; CancellationTokenRegistration cancellationTokenRegistration; + bool cancelImmediately; bool completed; UniTaskCompletionSourceCore core; @@ -127,6 +128,7 @@ static AssetBundleRequestAllAssetsConfiguredSource() result.asyncOperation = asyncOperation; result.progress = progress; result.cancellationToken = cancellationToken; + result.cancelImmediately = cancelImmediately; result.completed = false; asyncOperation.completed += result.continuationAction; @@ -156,7 +158,10 @@ public UnityEngine.Object[] GetResult(short token) } finally { - TryReturn(); + if (!(cancelImmediately && cancellationToken.IsCancellationRequested)) + { + TryReturn(); + } } } @@ -216,6 +221,7 @@ bool TryReturn() progress = default; cancellationToken = default; cancellationTokenRegistration.Dispose(); + cancelImmediately = default; return pool.TryPush(this); } @@ -223,19 +229,17 @@ void Continuation(AsyncOperation _) { if (completed) { - TryReturn(); + return; + } + + completed = true; + if (cancellationToken.IsCancellationRequested) + { + core.TrySetCanceled(cancellationToken); } else { - completed = true; - if (cancellationToken.IsCancellationRequested) - { - core.TrySetCanceled(cancellationToken); - } - else - { - core.TrySetResult(asyncOperation.allAssets); - } + core.TrySetResult(asyncOperation.allAssets); } } } diff --git a/src/UniTask/Assets/Plugins/UniTask/Runtime/UnityAsyncExtensions.AsyncGPUReadback.cs b/src/UniTask/Assets/Plugins/UniTask/Runtime/UnityAsyncExtensions.AsyncGPUReadback.cs index 5d73dc1a..a363be7a 100644 --- a/src/UniTask/Assets/Plugins/UniTask/Runtime/UnityAsyncExtensions.AsyncGPUReadback.cs +++ b/src/UniTask/Assets/Plugins/UniTask/Runtime/UnityAsyncExtensions.AsyncGPUReadback.cs @@ -45,7 +45,7 @@ static AsyncGPUReadbackRequestAwaiterConfiguredSource() AsyncGPUReadbackRequest asyncOperation; CancellationToken cancellationToken; CancellationTokenRegistration cancellationTokenRegistration; - + bool cancelImmediately; UniTaskCompletionSourceCore core; AsyncGPUReadbackRequestAwaiterConfiguredSource() @@ -66,6 +66,7 @@ public static IUniTaskSource Create(AsyncGPUReadbackReq result.asyncOperation = asyncOperation; result.cancellationToken = cancellationToken; + result.cancelImmediately = cancelImmediately; if (cancelImmediately && cancellationToken.CanBeCanceled) { @@ -92,7 +93,10 @@ public AsyncGPUReadbackRequest GetResult(short token) } finally { - TryReturn(); + if (!(cancelImmediately && cancellationToken.IsCancellationRequested)) + { + TryReturn(); + } } } @@ -146,6 +150,7 @@ bool TryReturn() asyncOperation = default; cancellationToken = default; cancellationTokenRegistration.Dispose(); + cancelImmediately = default; return pool.TryPush(this); } } diff --git a/src/UniTask/Assets/Plugins/UniTask/Runtime/UnityAsyncExtensions.cs b/src/UniTask/Assets/Plugins/UniTask/Runtime/UnityAsyncExtensions.cs index b9cd1c9f..5a5ea1c1 100644 --- a/src/UniTask/Assets/Plugins/UniTask/Runtime/UnityAsyncExtensions.cs +++ b/src/UniTask/Assets/Plugins/UniTask/Runtime/UnityAsyncExtensions.cs @@ -97,6 +97,7 @@ static AsyncOperationConfiguredSource() IProgress progress; CancellationToken cancellationToken; CancellationTokenRegistration cancellationTokenRegistration; + bool cancelImmediately; bool completed; UniTaskCompletionSourceCore core; @@ -123,6 +124,7 @@ public static IUniTaskSource Create(AsyncOperation asyncOperation, PlayerLoopTim result.asyncOperation = asyncOperation; result.progress = progress; result.cancellationToken = cancellationToken; + result.cancelImmediately = cancelImmediately; result.completed = false; asyncOperation.completed += result.continuationAction; @@ -152,7 +154,10 @@ public void GetResult(short token) } finally { - TryReturn(); + if (!(cancelImmediately && cancellationToken.IsCancellationRequested)) + { + TryReturn(); + } } } @@ -209,6 +214,7 @@ bool TryReturn() progress = default; cancellationToken = default; cancellationTokenRegistration.Dispose(); + cancelImmediately = default; return pool.TryPush(this); } @@ -216,19 +222,16 @@ void Continuation(AsyncOperation _) { if (completed) { - TryReturn(); + return; + } + completed = true; + if (cancellationToken.IsCancellationRequested) + { + core.TrySetCanceled(cancellationToken); } else { - completed = true; - if (cancellationToken.IsCancellationRequested) - { - core.TrySetCanceled(cancellationToken); - } - else - { - core.TrySetResult(AsyncUnit.Default); - } + core.TrySetResult(AsyncUnit.Default); } } } @@ -320,6 +323,7 @@ static ResourceRequestConfiguredSource() IProgress progress; CancellationToken cancellationToken; CancellationTokenRegistration cancellationTokenRegistration; + bool cancelImmediately; bool completed; UniTaskCompletionSourceCore core; @@ -346,6 +350,7 @@ static ResourceRequestConfiguredSource() result.asyncOperation = asyncOperation; result.progress = progress; result.cancellationToken = cancellationToken; + result.cancelImmediately = cancelImmediately; result.completed = false; asyncOperation.completed += result.continuationAction; @@ -375,7 +380,10 @@ public UnityEngine.Object GetResult(short token) } finally { - TryReturn(); + if (!(cancelImmediately && cancellationToken.IsCancellationRequested)) + { + TryReturn(); + } } } @@ -436,6 +444,7 @@ bool TryReturn() progress = default; cancellationToken = default; cancellationTokenRegistration.Dispose(); + cancelImmediately = default; return pool.TryPush(this); } @@ -443,19 +452,16 @@ void Continuation(AsyncOperation _) { if (completed) { - TryReturn(); + return; + } + completed = true; + if (cancellationToken.IsCancellationRequested) + { + core.TrySetCanceled(cancellationToken); } else { - completed = true; - if (cancellationToken.IsCancellationRequested) - { - core.TrySetCanceled(cancellationToken); - } - else - { - core.TrySetResult(asyncOperation.asset); - } + core.TrySetResult(asyncOperation.asset); } } } @@ -548,6 +554,7 @@ static AssetBundleRequestConfiguredSource() IProgress progress; CancellationToken cancellationToken; CancellationTokenRegistration cancellationTokenRegistration; + bool cancelImmediately; bool completed; UniTaskCompletionSourceCore core; @@ -574,6 +581,7 @@ static AssetBundleRequestConfiguredSource() result.asyncOperation = asyncOperation; result.progress = progress; result.cancellationToken = cancellationToken; + result.cancelImmediately = cancelImmediately; result.completed = false; asyncOperation.completed += result.continuationAction; @@ -603,7 +611,10 @@ public UnityEngine.Object GetResult(short token) } finally { - TryReturn(); + if (!(cancelImmediately && cancellationToken.IsCancellationRequested)) + { + TryReturn(); + } } } @@ -664,6 +675,7 @@ bool TryReturn() progress = default; cancellationToken = default; cancellationTokenRegistration.Dispose(); + cancelImmediately = default; return pool.TryPush(this); } @@ -671,19 +683,16 @@ void Continuation(AsyncOperation _) { if (completed) { - TryReturn(); + return; + } + completed = true; + if (cancellationToken.IsCancellationRequested) + { + core.TrySetCanceled(cancellationToken); } else { - completed = true; - if (cancellationToken.IsCancellationRequested) - { - core.TrySetCanceled(cancellationToken); - } - else - { - core.TrySetResult(asyncOperation.asset); - } + core.TrySetResult(asyncOperation.asset); } } } @@ -777,6 +786,7 @@ static AssetBundleCreateRequestConfiguredSource() IProgress progress; CancellationToken cancellationToken; CancellationTokenRegistration cancellationTokenRegistration; + bool cancelImmediately; bool completed; UniTaskCompletionSourceCore core; @@ -803,6 +813,7 @@ public static IUniTaskSource Create(AssetBundleCreateRequest asyncO result.asyncOperation = asyncOperation; result.progress = progress; result.cancellationToken = cancellationToken; + result.cancelImmediately = cancelImmediately; result.completed = false; asyncOperation.completed += result.continuationAction; @@ -832,7 +843,10 @@ public AssetBundle GetResult(short token) } finally { - TryReturn(); + if (!(cancelImmediately && cancellationToken.IsCancellationRequested)) + { + TryReturn(); + } } } @@ -893,6 +907,7 @@ bool TryReturn() progress = default; cancellationToken = default; cancellationTokenRegistration.Dispose(); + cancelImmediately = default; return pool.TryPush(this); } @@ -900,19 +915,16 @@ void Continuation(AsyncOperation _) { if (completed) { - TryReturn(); + return; + } + completed = true; + if (cancellationToken.IsCancellationRequested) + { + core.TrySetCanceled(cancellationToken); } else { - completed = true; - if (cancellationToken.IsCancellationRequested) - { - core.TrySetCanceled(cancellationToken); - } - else - { - core.TrySetResult(asyncOperation.assetBundle); - } + core.TrySetResult(asyncOperation.assetBundle); } } } @@ -1021,6 +1033,7 @@ static UnityWebRequestAsyncOperationConfiguredSource() IProgress progress; CancellationToken cancellationToken; CancellationTokenRegistration cancellationTokenRegistration; + bool cancelImmediately; bool completed; UniTaskCompletionSourceCore core; @@ -1047,6 +1060,7 @@ public static IUniTaskSource Create(UnityWebRequestAsyncOperati result.asyncOperation = asyncOperation; result.progress = progress; result.cancellationToken = cancellationToken; + result.cancelImmediately = cancelImmediately; result.completed = false; asyncOperation.completed += result.continuationAction; @@ -1077,7 +1091,10 @@ public UnityWebRequest GetResult(short token) } finally { - TryReturn(); + if (!(cancelImmediately && cancellationToken.IsCancellationRequested)) + { + TryReturn(); + } } } @@ -1146,6 +1163,7 @@ bool TryReturn() progress = default; cancellationToken = default; cancellationTokenRegistration.Dispose(); + cancelImmediately = default; return pool.TryPush(this); } @@ -1153,23 +1171,20 @@ void Continuation(AsyncOperation _) { if (completed) { - TryReturn(); + return; + } + completed = true; + if (cancellationToken.IsCancellationRequested) + { + core.TrySetCanceled(cancellationToken); + } + else if (asyncOperation.webRequest.IsError()) + { + core.TrySetException(new UnityWebRequestException(asyncOperation.webRequest)); } else { - completed = true; - if (cancellationToken.IsCancellationRequested) - { - core.TrySetCanceled(cancellationToken); - } - else if (asyncOperation.webRequest.IsError()) - { - core.TrySetException(new UnityWebRequestException(asyncOperation.webRequest)); - } - else - { - core.TrySetResult(asyncOperation.webRequest); - } + core.TrySetResult(asyncOperation.webRequest); } } } diff --git a/src/UniTask/Assets/Plugins/UniTask/Runtime/UnityAsyncExtensions.tt b/src/UniTask/Assets/Plugins/UniTask/Runtime/UnityAsyncExtensions.tt index 0516fef1..e2437df0 100644 --- a/src/UniTask/Assets/Plugins/UniTask/Runtime/UnityAsyncExtensions.tt +++ b/src/UniTask/Assets/Plugins/UniTask/Runtime/UnityAsyncExtensions.tt @@ -165,6 +165,7 @@ namespace Cysharp.Threading.Tasks IProgress progress; CancellationToken cancellationToken; CancellationTokenRegistration cancellationTokenRegistration; + bool cancelImmediately; bool completed; UniTaskCompletionSourceCore<<#= IsVoid(t) ? "AsyncUnit" : t.returnType #>> core; @@ -191,6 +192,7 @@ namespace Cysharp.Threading.Tasks result.asyncOperation = asyncOperation; result.progress = progress; result.cancellationToken = cancellationToken; + result.cancelImmediately = cancelImmediately; result.completed = false; asyncOperation.completed += result.continuationAction; @@ -227,7 +229,10 @@ namespace Cysharp.Threading.Tasks } finally { - TryReturn(); + if (!(cancelImmediately && cancellationToken.IsCancellationRequested)) + { + TryReturn(); + } } } @@ -304,6 +309,7 @@ namespace Cysharp.Threading.Tasks progress = default; cancellationToken = default; cancellationTokenRegistration.Dispose(); + cancelImmediately = default; return pool.TryPush(this); } @@ -311,31 +317,28 @@ namespace Cysharp.Threading.Tasks { if (completed) { - TryReturn(); + return; } - else + completed = true; + if (cancellationToken.IsCancellationRequested) { - completed = true; - if (cancellationToken.IsCancellationRequested) - { - core.TrySetCanceled(cancellationToken); - } + core.TrySetCanceled(cancellationToken); + } <# if(IsUnityWebRequest(t)) { #> - else if (asyncOperation.webRequest.IsError()) - { - core.TrySetException(new UnityWebRequestException(asyncOperation.webRequest)); - } - else - { - core.TrySetResult(asyncOperation.webRequest); - } + else if (asyncOperation.webRequest.IsError()) + { + core.TrySetException(new UnityWebRequestException(asyncOperation.webRequest)); + } + else + { + core.TrySetResult(asyncOperation.webRequest); + } <# } else { #> - else - { - core.TrySetResult(<#= IsVoid(t) ? "AsyncUnit.Default" : $"asyncOperation.{t.returnField}" #>); - } -<# } #> + else + { + core.TrySetResult(<#= IsVoid(t) ? "AsyncUnit.Default" : $"asyncOperation.{t.returnField}" #>); } +<# } #> } }