From f59c56506f59d126ac44099b78b612a27832759d Mon Sep 17 00:00:00 2001 From: neuecc Date: Sat, 23 May 2020 02:07:46 +0900 Subject: [PATCH] Remove ConfigureAwait method from all async object extensions(renamed to ToUniTask). Add WithCancellation method to all async object extensions. Improved performance when async object is done. --- .../Runtime/EnumeratorAsyncExtensions.cs | 9 ++- .../External/AddressableAsyncExtensions.cs | 30 ++++++---- .../External/DoTweenAsyncExtensions.cs | 6 +- .../UniTask/Runtime/UniTaskExtensions.cs | 30 ---------- .../Runtime/UnityAsyncExtensions.Jobs.cs | 18 +----- .../UniTask/Runtime/UnityAsyncExtensions.cs | 59 ++++++++++--------- src/UniTask/Assets/Scenes/SandboxMain.cs | 4 +- src/UniTask/Assets/Tests/AsyncTest.cs | 1 - .../Assets/Tests/Editor/AsyncTestEditor.cs | 1 - 9 files changed, 62 insertions(+), 96 deletions(-) diff --git a/src/UniTask/Assets/Plugins/UniTask/Runtime/EnumeratorAsyncExtensions.cs b/src/UniTask/Assets/Plugins/UniTask/Runtime/EnumeratorAsyncExtensions.cs index d27e17c..b5cf765 100644 --- a/src/UniTask/Assets/Plugins/UniTask/Runtime/EnumeratorAsyncExtensions.cs +++ b/src/UniTask/Assets/Plugins/UniTask/Runtime/EnumeratorAsyncExtensions.cs @@ -14,16 +14,19 @@ namespace Cysharp.Threading.Tasks { public static UniTask.Awaiter GetAwaiter(this IEnumerator enumerator) { + Error.ThrowArgumentNullException(enumerator, nameof(enumerator)); return new UniTask(EnumeratorPromise.Create(enumerator, PlayerLoopTiming.Update, CancellationToken.None, out var token), token).GetAwaiter(); } - public static UniTask ToUniTask(this IEnumerator enumerator) + public static UniTask WithCancellation(this IEnumerator enumerator, CancellationToken cancellationToken) { - return new UniTask(EnumeratorPromise.Create(enumerator, PlayerLoopTiming.Update, CancellationToken.None, out var token), token); + Error.ThrowArgumentNullException(enumerator, nameof(enumerator)); + return new UniTask(EnumeratorPromise.Create(enumerator, PlayerLoopTiming.Update, cancellationToken, out var token), token); } - public static UniTask ConfigureAwait(this IEnumerator enumerator, PlayerLoopTiming timing = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken)) + public static UniTask ToUniTask(this IEnumerator enumerator, PlayerLoopTiming timing = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken)) { + Error.ThrowArgumentNullException(enumerator, nameof(enumerator)); return new UniTask(EnumeratorPromise.Create(enumerator, timing, cancellationToken, out var token), token); } diff --git a/src/UniTask/Assets/Plugins/UniTask/Runtime/External/AddressableAsyncExtensions.cs b/src/UniTask/Assets/Plugins/UniTask/Runtime/External/AddressableAsyncExtensions.cs index 934e58f..8b81e63 100644 --- a/src/UniTask/Assets/Plugins/UniTask/Runtime/External/AddressableAsyncExtensions.cs +++ b/src/UniTask/Assets/Plugins/UniTask/Runtime/External/AddressableAsyncExtensions.cs @@ -13,21 +13,23 @@ namespace Cysharp.Threading.Tasks { public static class AddressableAsyncExtensions { -#region AsyncOperationHandle + #region AsyncOperationHandle public static AsyncOperationHandleAwaiter GetAwaiter(this AsyncOperationHandle handle) { return new AsyncOperationHandleAwaiter(handle); } - public static UniTask ToUniTask(this AsyncOperationHandle handle) + public static UniTask WithCancellation(this AsyncOperationHandle handle, CancellationToken cancellationToken) { - return new UniTask(AsyncOperationHandleConfiguredSource.Create(handle, PlayerLoopTiming.Update, null, CancellationToken.None, out var token), token); + if (handle.IsDone) return UniTask.CompletedTask; + return new UniTask(AsyncOperationHandleConfiguredSource.Create(handle, PlayerLoopTiming.Update, null, cancellationToken, out var token), token); } - public static UniTask ConfigureAwait(this AsyncOperationHandle handle, IProgress progress = null, PlayerLoopTiming timing = PlayerLoopTiming.Update, CancellationToken cancellation = default(CancellationToken)) + public static UniTask ToUniTask(this AsyncOperationHandle handle, IProgress progress = null, PlayerLoopTiming timing = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken)) { - return new UniTask(AsyncOperationHandleConfiguredSource.Create(handle, timing, progress, cancellation, out var token), token); + if (handle.IsDone) return UniTask.CompletedTask; + return new UniTask(AsyncOperationHandleConfiguredSource.Create(handle, timing, progress, cancellationToken, out var token), token); } public struct AsyncOperationHandleAwaiter : ICriticalNotifyCompletion @@ -75,7 +77,7 @@ namespace Cysharp.Threading.Tasks } } - class AsyncOperationHandleConfiguredSource : IUniTaskSource, IPlayerLoopItem, IPromisePoolItem + sealed class AsyncOperationHandleConfiguredSource : IUniTaskSource, IPlayerLoopItem, IPromisePoolItem { static readonly PromisePool pool = new PromisePool(); @@ -185,22 +187,24 @@ namespace Cysharp.Threading.Tasks } } -#endregion + #endregion -#region AsyncOperationHandle_T + #region AsyncOperationHandle_T public static AsyncOperationHandleAwaiter GetAwaiter(this AsyncOperationHandle handle) { return new AsyncOperationHandleAwaiter(handle); } - public static UniTask ToUniTask(this AsyncOperationHandle handle) + public static UniTask WithCancellation(this AsyncOperationHandle handle, CancellationToken cancellationToken) { - return new UniTask(AsyncOperationHandleConfiguredSource.Create(handle, PlayerLoopTiming.Update, null, CancellationToken.None, out var token), token); + if (handle.IsDone) return UniTask.FromResult(handle.Result); + return new UniTask(AsyncOperationHandleConfiguredSource.Create(handle, PlayerLoopTiming.Update, null, cancellationToken, out var token), token); } - public static UniTask ConfigureAwait(this AsyncOperationHandle handle, IProgress progress = null, PlayerLoopTiming timing = PlayerLoopTiming.Update, CancellationToken cancellation = default(CancellationToken)) + public static UniTask ToUniTask(this AsyncOperationHandle handle, IProgress progress = null, PlayerLoopTiming timing = PlayerLoopTiming.Update, CancellationToken cancellation = default(CancellationToken)) { + if (handle.IsDone) return UniTask.FromResult(handle.Result); return new UniTask(AsyncOperationHandleConfiguredSource.Create(handle, timing, progress, cancellation, out var token), token); } @@ -250,7 +254,7 @@ namespace Cysharp.Threading.Tasks } } - class AsyncOperationHandleConfiguredSource : IUniTaskSource, IPlayerLoopItem, IPromisePoolItem + sealed class AsyncOperationHandleConfiguredSource : IUniTaskSource, IPlayerLoopItem, IPromisePoolItem { static readonly PromisePool> pool = new PromisePool>(); @@ -366,7 +370,7 @@ namespace Cysharp.Threading.Tasks } } -#endregion + #endregion } } diff --git a/src/UniTask/Assets/Plugins/UniTask/Runtime/External/DoTweenAsyncExtensions.cs b/src/UniTask/Assets/Plugins/UniTask/Runtime/External/DoTweenAsyncExtensions.cs index 1779289..3696282 100644 --- a/src/UniTask/Assets/Plugins/UniTask/Runtime/External/DoTweenAsyncExtensions.cs +++ b/src/UniTask/Assets/Plugins/UniTask/Runtime/External/DoTweenAsyncExtensions.cs @@ -36,12 +36,16 @@ namespace Cysharp.Threading.Tasks public static UniTask WithCancellation(this Tween tween, CancellationToken cancellationToken = default) { Error.ThrowArgumentNullException(tween, nameof(tween)); + + if (!tween.IsActive()) return UniTask.CompletedTask; return new UniTask(TweenConfiguredSource.Create(tween, TweenCancelBehaviour.Kill, cancellationToken, out var token), token); } public static UniTask ToUniTask(this Tween tween, TweenCancelBehaviour tweenCancelBehaviour = TweenCancelBehaviour.Kill, CancellationToken cancellationToken = default) { Error.ThrowArgumentNullException(tween, nameof(tween)); + + if (!tween.IsActive()) return UniTask.CompletedTask; return new UniTask(TweenConfiguredSource.Create(tween, tweenCancelBehaviour, cancellationToken, out var token), token); } @@ -79,7 +83,7 @@ namespace Cysharp.Threading.Tasks } } - class TweenConfiguredSource : IUniTaskSource, IPromisePoolItem + sealed class TweenConfiguredSource : IUniTaskSource, IPromisePoolItem { static readonly PromisePool pool = new PromisePool(); static Action CancellationCallbackDelegate = CancellationCallback; diff --git a/src/UniTask/Assets/Plugins/UniTask/Runtime/UniTaskExtensions.cs b/src/UniTask/Assets/Plugins/UniTask/Runtime/UniTaskExtensions.cs index bd476f7..2c76ce1 100644 --- a/src/UniTask/Assets/Plugins/UniTask/Runtime/UniTaskExtensions.cs +++ b/src/UniTask/Assets/Plugins/UniTask/Runtime/UniTaskExtensions.cs @@ -559,36 +559,6 @@ namespace Cysharp.Threading.Tasks return await continuationFunction(); } -#if UNITY_2018_3_OR_NEWER - - public static async UniTask ConfigureAwait(this Task task, PlayerLoopTiming timing) - { - await task.ConfigureAwait(false); - await UniTask.Yield(timing); - } - - public static async UniTask ConfigureAwait(this Task task, PlayerLoopTiming timing) - { - var v = await task.ConfigureAwait(false); - await UniTask.Yield(timing); - return v; - } - - public static async UniTask ConfigureAwait(this UniTask task, PlayerLoopTiming timing) - { - await task; - await UniTask.Yield(timing); - } - - public static async UniTask ConfigureAwait(this UniTask task, PlayerLoopTiming timing) - { - var v = await task; - await UniTask.Yield(timing); - return v; - } - -#endif - public static async UniTask Unwrap(this UniTask> task) { return await await task; diff --git a/src/UniTask/Assets/Plugins/UniTask/Runtime/UnityAsyncExtensions.Jobs.cs b/src/UniTask/Assets/Plugins/UniTask/Runtime/UnityAsyncExtensions.Jobs.cs index 785fe0b..370e446 100644 --- a/src/UniTask/Assets/Plugins/UniTask/Runtime/UnityAsyncExtensions.Jobs.cs +++ b/src/UniTask/Assets/Plugins/UniTask/Runtime/UnityAsyncExtensions.Jobs.cs @@ -28,22 +28,8 @@ namespace Cysharp.Threading.Tasks return new UniTask(handler, token).GetAwaiter(); } - - public static UniTask ToUniTask(this JobHandle jobHandle) - { - var handler = JobHandlePromise.Create(jobHandle, out var token); - { - PlayerLoopHelper.AddAction(PlayerLoopTiming.EarlyUpdate, handler); - PlayerLoopHelper.AddAction(PlayerLoopTiming.PreUpdate, handler); - PlayerLoopHelper.AddAction(PlayerLoopTiming.Update, handler); - PlayerLoopHelper.AddAction(PlayerLoopTiming.PreLateUpdate, handler); - PlayerLoopHelper.AddAction(PlayerLoopTiming.PostLateUpdate, handler); - } - - return new UniTask(handler, token); - } - - public static UniTask ConfigureAwait(this JobHandle jobHandle, PlayerLoopTiming waitTiming) + + public static UniTask ToUniTask(this JobHandle jobHandle, PlayerLoopTiming waitTiming) { var handler = JobHandlePromise.Create(jobHandle, out var token); { diff --git a/src/UniTask/Assets/Plugins/UniTask/Runtime/UnityAsyncExtensions.cs b/src/UniTask/Assets/Plugins/UniTask/Runtime/UnityAsyncExtensions.cs index bfa6ee6..a947956 100644 --- a/src/UniTask/Assets/Plugins/UniTask/Runtime/UnityAsyncExtensions.cs +++ b/src/UniTask/Assets/Plugins/UniTask/Runtime/UnityAsyncExtensions.cs @@ -21,17 +21,18 @@ namespace Cysharp.Threading.Tasks return new AsyncOperationAwaiter(asyncOperation); } - public static UniTask ToUniTask(this AsyncOperation asyncOperation) + public static UniTask WithCancellation(this AsyncOperation asyncOperation, CancellationToken cancellationToken) { Error.ThrowArgumentNullException(asyncOperation, nameof(asyncOperation)); - return new UniTask(AsyncOperationConfiguredSource.Create(asyncOperation, PlayerLoopTiming.Update, null, CancellationToken.None, out var token), token); + if (asyncOperation.isDone) return UniTask.CompletedTask; + return new UniTask(AsyncOperationConfiguredSource.Create(asyncOperation, PlayerLoopTiming.Update, null, cancellationToken, out var token), token); } - public static UniTask ConfigureAwait(this AsyncOperation asyncOperation, IProgress progress = null, PlayerLoopTiming timing = PlayerLoopTiming.Update, CancellationToken cancellation = default(CancellationToken)) + public static UniTask ToUniTask(this AsyncOperation asyncOperation, IProgress progress = null, PlayerLoopTiming timing = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken)) { Error.ThrowArgumentNullException(asyncOperation, nameof(asyncOperation)); - - return new UniTask(AsyncOperationConfiguredSource.Create(asyncOperation, timing, progress, cancellation, out var token), token); + if (asyncOperation.isDone) return UniTask.CompletedTask; + return new UniTask(AsyncOperationConfiguredSource.Create(asyncOperation, timing, progress, cancellationToken, out var token), token); } public struct AsyncOperationAwaiter : ICriticalNotifyCompletion @@ -188,18 +189,18 @@ namespace Cysharp.Threading.Tasks return new ResourceRequestAwaiter(asyncOperation); } - public static UniTask ToUniTask(this ResourceRequest asyncOperation) + public static UniTask WithCancellation(this ResourceRequest asyncOperation, CancellationToken cancellationToken) { Error.ThrowArgumentNullException(asyncOperation, nameof(asyncOperation)); - - return new UniTask(ResourceRequestConfiguredSource.Create(asyncOperation, PlayerLoopTiming.Update, null, CancellationToken.None, out var token), token); + if (asyncOperation.isDone) return UniTask.FromResult(asyncOperation.asset); + return new UniTask(ResourceRequestConfiguredSource.Create(asyncOperation, PlayerLoopTiming.Update, null, cancellationToken, out var token), token); } - public static UniTask ConfigureAwait(this ResourceRequest asyncOperation, IProgress progress = null, PlayerLoopTiming timing = PlayerLoopTiming.Update, CancellationToken cancellation = default(CancellationToken)) + public static UniTask ToUniTask(this ResourceRequest asyncOperation, IProgress progress = null, PlayerLoopTiming timing = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken)) { Error.ThrowArgumentNullException(asyncOperation, nameof(asyncOperation)); - - return new UniTask(ResourceRequestConfiguredSource.Create(asyncOperation, timing, progress, cancellation, out var token), token); + if (asyncOperation.isDone) return UniTask.FromResult(asyncOperation.asset); + return new UniTask(ResourceRequestConfiguredSource.Create(asyncOperation, timing, progress, cancellationToken, out var token), token); } public struct ResourceRequestAwaiter : ICriticalNotifyCompletion @@ -365,18 +366,18 @@ namespace Cysharp.Threading.Tasks return new AssetBundleRequestAwaiter(asyncOperation); } - public static UniTask ToUniTask(this AssetBundleRequest asyncOperation) + public static UniTask WithCancellation(this AssetBundleRequest asyncOperation, CancellationToken cancellationToken) { Error.ThrowArgumentNullException(asyncOperation, nameof(asyncOperation)); - - return new UniTask(AssetBundleRequestConfiguredSource.Create(asyncOperation, PlayerLoopTiming.Update, null, CancellationToken.None, out var token), token); + if (asyncOperation.isDone) return UniTask.FromResult(asyncOperation.asset); + return new UniTask(AssetBundleRequestConfiguredSource.Create(asyncOperation, PlayerLoopTiming.Update, null, cancellationToken, out var token), token); } - public static UniTask ConfigureAwait(this AssetBundleRequest asyncOperation, IProgress progress = null, PlayerLoopTiming timing = PlayerLoopTiming.Update, CancellationToken cancellation = default(CancellationToken)) + public static UniTask ToUniTask(this AssetBundleRequest asyncOperation, IProgress progress = null, PlayerLoopTiming timing = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken)) { Error.ThrowArgumentNullException(asyncOperation, nameof(asyncOperation)); - - return new UniTask(AssetBundleRequestConfiguredSource.Create(asyncOperation, timing, progress, cancellation, out var token), token); + if (asyncOperation.isDone) return UniTask.FromResult(asyncOperation.asset); + return new UniTask(AssetBundleRequestConfiguredSource.Create(asyncOperation, timing, progress, cancellationToken, out var token), token); } public struct AssetBundleRequestAwaiter : ICriticalNotifyCompletion @@ -542,18 +543,18 @@ namespace Cysharp.Threading.Tasks return new AssetBundleCreateRequestAwaiter(asyncOperation); } - public static UniTask ToUniTask(this AssetBundleCreateRequest asyncOperation) + public static UniTask WithCancellation(this AssetBundleCreateRequest asyncOperation, CancellationToken cancellationToken) { Error.ThrowArgumentNullException(asyncOperation, nameof(asyncOperation)); - - return new UniTask(AssetBundleCreateRequestConfiguredSource.Create(asyncOperation, PlayerLoopTiming.Update, null, CancellationToken.None, out var token), token); + if (asyncOperation.isDone) return UniTask.FromResult(asyncOperation.assetBundle); + return new UniTask(AssetBundleCreateRequestConfiguredSource.Create(asyncOperation, PlayerLoopTiming.Update, null, cancellationToken, out var token), token); } - public static UniTask ConfigureAwait(this AssetBundleCreateRequest asyncOperation, IProgress progress = null, PlayerLoopTiming timing = PlayerLoopTiming.Update, CancellationToken cancellation = default(CancellationToken)) + public static UniTask ToUniTask(this AssetBundleCreateRequest asyncOperation, IProgress progress = null, PlayerLoopTiming timing = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken)) { Error.ThrowArgumentNullException(asyncOperation, nameof(asyncOperation)); - - return new UniTask(AssetBundleCreateRequestConfiguredSource.Create(asyncOperation, timing, progress, cancellation, out var token), token); + if (asyncOperation.isDone) return UniTask.FromResult(asyncOperation.assetBundle); + return new UniTask(AssetBundleCreateRequestConfiguredSource.Create(asyncOperation, timing, progress, cancellationToken, out var token), token); } public struct AssetBundleCreateRequestAwaiter : ICriticalNotifyCompletion @@ -720,18 +721,18 @@ namespace Cysharp.Threading.Tasks return new UnityWebRequestAsyncOperationAwaiter(asyncOperation); } - public static UniTask ToUniTask(this UnityWebRequestAsyncOperation asyncOperation) + public static UniTask WithCancellation(this UnityWebRequestAsyncOperation asyncOperation, CancellationToken cancellationToken) { Error.ThrowArgumentNullException(asyncOperation, nameof(asyncOperation)); - - return new UniTask(UnityWebRequestAsyncOperationConfiguredSource.Create(asyncOperation, PlayerLoopTiming.Update, null, CancellationToken.None, out var token), token); + if (asyncOperation.isDone) return UniTask.FromResult(asyncOperation.webRequest); + return new UniTask(UnityWebRequestAsyncOperationConfiguredSource.Create(asyncOperation, PlayerLoopTiming.Update, null, cancellationToken, out var token), token); } - public static UniTask ConfigureAwait(this UnityWebRequestAsyncOperation asyncOperation, IProgress progress = null, PlayerLoopTiming timing = PlayerLoopTiming.Update, CancellationToken cancellation = default(CancellationToken)) + public static UniTask ToUniTask(this UnityWebRequestAsyncOperation asyncOperation, IProgress progress = null, PlayerLoopTiming timing = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken)) { Error.ThrowArgumentNullException(asyncOperation, nameof(asyncOperation)); - - return new UniTask(UnityWebRequestAsyncOperationConfiguredSource.Create(asyncOperation, timing, progress, cancellation, out var token), token); + if (asyncOperation.isDone) return UniTask.FromResult(asyncOperation.webRequest); + return new UniTask(UnityWebRequestAsyncOperationConfiguredSource.Create(asyncOperation, timing, progress, cancellationToken, out var token), token); } public struct UnityWebRequestAsyncOperationAwaiter : ICriticalNotifyCompletion diff --git a/src/UniTask/Assets/Scenes/SandboxMain.cs b/src/UniTask/Assets/Scenes/SandboxMain.cs index 8900db5..49c6411 100644 --- a/src/UniTask/Assets/Scenes/SandboxMain.cs +++ b/src/UniTask/Assets/Scenes/SandboxMain.cs @@ -244,7 +244,7 @@ public class SandboxMain : MonoBehaviour } - async UniTaskVoid Start() + void Start() { //UniTaskAsyncEnumerable.EveryValueChanged(mcc, x => x.MyProperty) // .Do(_ => { }, () => Debug.Log("COMPLETED")) @@ -535,7 +535,7 @@ public class SandboxMain : MonoBehaviour public class ShowPlayerLoop { - [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)] + // [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)] static void Init() { var playerLoop = UnityEngine.LowLevel.PlayerLoop.GetDefaultPlayerLoop(); diff --git a/src/UniTask/Assets/Tests/AsyncTest.cs b/src/UniTask/Assets/Tests/AsyncTest.cs index 56a8006..2cdebb0 100644 --- a/src/UniTask/Assets/Tests/AsyncTest.cs +++ b/src/UniTask/Assets/Tests/AsyncTest.cs @@ -124,7 +124,6 @@ namespace Cysharp.Threading.TasksTests public IEnumerator BothEnumeratorCheck() => UniTask.ToCoroutine(async () => { await ToaruCoroutineEnumerator(); // wait 5 frame:) - await ToaruCoroutineEnumerator().ConfigureAwait(PlayerLoopTiming.PostLateUpdate); }); [UnityTest] diff --git a/src/UniTask/Assets/Tests/Editor/AsyncTestEditor.cs b/src/UniTask/Assets/Tests/Editor/AsyncTestEditor.cs index 12af94d..9c36a1c 100644 --- a/src/UniTask/Assets/Tests/Editor/AsyncTestEditor.cs +++ b/src/UniTask/Assets/Tests/Editor/AsyncTestEditor.cs @@ -124,7 +124,6 @@ namespace Cysharp.Threading.TasksTests public IEnumerator BothEnumeratorCheck() => UniTask.ToCoroutine(async () => { await ToaruCoroutineEnumerator(); // wait 5 frame:) - await ToaruCoroutineEnumerator().ConfigureAwait(PlayerLoopTiming.PostLateUpdate); }); [UnityTest]