#if CSHARP_7_OR_LATER || (UNITY_2018_3_OR_NEWER && (NET_STANDARD_2_0 || NET_4_6)) #pragma warning disable CS1591 // Missing XML comment for publicly visible type or member using System; using System.Runtime.CompilerServices; using System.Runtime.ExceptionServices; using System.Threading; namespace UniRx.Async { public partial struct UniTask { public static async UniTask<(T1 result1, T2 result2)> WhenAll(UniTask task1, UniTask task2) { return await new WhenAllPromise(task1, task2); } public static async UniTask<(T1 result1, T2 result2, T3 result3)> WhenAll(UniTask task1, UniTask task2, UniTask task3) { return await new WhenAllPromise(task1, task2, task3); } public static async UniTask<(T1 result1, T2 result2, T3 result3, T4 result4)> WhenAll(UniTask task1, UniTask task2, UniTask task3, UniTask task4) { return await new WhenAllPromise(task1, task2, task3, task4); } public static async UniTask<(T1 result1, T2 result2, T3 result3, T4 result4, T5 result5)> WhenAll(UniTask task1, UniTask task2, UniTask task3, UniTask task4, UniTask task5) { return await new WhenAllPromise(task1, task2, task3, task4, task5); } public static async UniTask<(T1 result1, T2 result2, T3 result3, T4 result4, T5 result5, T6 result6)> WhenAll(UniTask task1, UniTask task2, UniTask task3, UniTask task4, UniTask task5, UniTask task6) { return await new WhenAllPromise(task1, task2, task3, task4, task5, task6); } public static async UniTask<(T1 result1, T2 result2, T3 result3, T4 result4, T5 result5, T6 result6, T7 result7)> WhenAll(UniTask task1, UniTask task2, UniTask task3, UniTask task4, UniTask task5, UniTask task6, UniTask task7) { return await new WhenAllPromise(task1, task2, task3, task4, task5, task6, task7); } class WhenAllPromise { const int MaxCount = 2; T1 result1; T2 result2; ExceptionDispatchInfo exception; int completeCount; Action whenComplete; public WhenAllPromise(UniTask task1, UniTask task2) { this.completeCount = 0; this.whenComplete = null; this.result1 = default(T1); this.result2 = default(T2); this.exception = null; RunTask1(task1); RunTask2(task2); } void TryCallContinuation() { var action = Interlocked.Exchange(ref whenComplete, null); if (action != null) { action.Invoke(); } } void RunTask1(UniTask task) { if (task.IsCompleted) { try { result1 = task.Result; } catch (Exception ex) { exception = ExceptionDispatchInfo.Capture(ex); TryCallContinuation(); return; } var count = Interlocked.Increment(ref completeCount); if (count == MaxCount) { TryCallContinuation(); } } else { RunTask1Async(task).Forget(); } } async UniTaskVoid RunTask1Async(UniTask task) { try { result1 = await task; } catch (Exception ex) { exception = ExceptionDispatchInfo.Capture(ex); TryCallContinuation(); return; } var count = Interlocked.Increment(ref completeCount); if (count == MaxCount) { TryCallContinuation(); } } void RunTask2(UniTask task) { if (task.IsCompleted) { try { result2 = task.Result; } catch (Exception ex) { exception = ExceptionDispatchInfo.Capture(ex); TryCallContinuation(); return; } var count = Interlocked.Increment(ref completeCount); if (count == MaxCount) { TryCallContinuation(); } } else { RunTask2Async(task).Forget(); } } async UniTaskVoid RunTask2Async(UniTask task) { try { result2 = await task; } catch (Exception ex) { exception = ExceptionDispatchInfo.Capture(ex); TryCallContinuation(); return; } var count = Interlocked.Increment(ref completeCount); if (count == MaxCount) { TryCallContinuation(); } } public Awaiter GetAwaiter() { return new Awaiter(this); } public struct Awaiter : ICriticalNotifyCompletion { WhenAllPromise parent; public Awaiter(WhenAllPromise parent) { this.parent = parent; } public bool IsCompleted { get { return parent.exception != null || parent.completeCount == MaxCount; } } public (T1, T2) GetResult() { if (parent.exception != null) { parent.exception.Throw(); } return (parent.result1, parent.result2); } public void OnCompleted(Action continuation) { UnsafeOnCompleted(continuation); } public void UnsafeOnCompleted(Action continuation) { parent.whenComplete = continuation; if (IsCompleted) { var action = Interlocked.Exchange(ref parent.whenComplete, null); if (action != null) { action(); } } } } } class WhenAllPromise { const int MaxCount = 3; T1 result1; T2 result2; T3 result3; ExceptionDispatchInfo exception; int completeCount; Action whenComplete; public WhenAllPromise(UniTask task1, UniTask task2, UniTask task3) { this.completeCount = 0; this.whenComplete = null; this.result1 = default(T1); this.result2 = default(T2); this.result3 = default(T3); this.exception = null; RunTask1(task1); RunTask2(task2); RunTask3(task3); } void TryCallContinuation() { var action = Interlocked.Exchange(ref whenComplete, null); if (action != null) { action.Invoke(); } } void RunTask1(UniTask task) { if (task.IsCompleted) { try { result1 = task.Result; } catch (Exception ex) { exception = ExceptionDispatchInfo.Capture(ex); TryCallContinuation(); return; } var count = Interlocked.Increment(ref completeCount); if (count == MaxCount) { TryCallContinuation(); } } else { RunTask1Async(task).Forget(); } } async UniTaskVoid RunTask1Async(UniTask task) { try { result1 = await task; } catch (Exception ex) { exception = ExceptionDispatchInfo.Capture(ex); TryCallContinuation(); return; } var count = Interlocked.Increment(ref completeCount); if (count == MaxCount) { TryCallContinuation(); } } void RunTask2(UniTask task) { if (task.IsCompleted) { try { result2 = task.Result; } catch (Exception ex) { exception = ExceptionDispatchInfo.Capture(ex); TryCallContinuation(); return; } var count = Interlocked.Increment(ref completeCount); if (count == MaxCount) { TryCallContinuation(); } } else { RunTask2Async(task).Forget(); } } async UniTaskVoid RunTask2Async(UniTask task) { try { result2 = await task; } catch (Exception ex) { exception = ExceptionDispatchInfo.Capture(ex); TryCallContinuation(); return; } var count = Interlocked.Increment(ref completeCount); if (count == MaxCount) { TryCallContinuation(); } } void RunTask3(UniTask task) { if (task.IsCompleted) { try { result3 = task.Result; } catch (Exception ex) { exception = ExceptionDispatchInfo.Capture(ex); TryCallContinuation(); return; } var count = Interlocked.Increment(ref completeCount); if (count == MaxCount) { TryCallContinuation(); } } else { RunTask3Async(task).Forget(); } } async UniTaskVoid RunTask3Async(UniTask task) { try { result3 = await task; } catch (Exception ex) { exception = ExceptionDispatchInfo.Capture(ex); TryCallContinuation(); return; } var count = Interlocked.Increment(ref completeCount); if (count == MaxCount) { TryCallContinuation(); } } public Awaiter GetAwaiter() { return new Awaiter(this); } public struct Awaiter : ICriticalNotifyCompletion { WhenAllPromise parent; public Awaiter(WhenAllPromise parent) { this.parent = parent; } public bool IsCompleted { get { return parent.exception != null || parent.completeCount == MaxCount; } } public (T1, T2, T3) GetResult() { if (parent.exception != null) { parent.exception.Throw(); } return (parent.result1, parent.result2, parent.result3); } public void OnCompleted(Action continuation) { UnsafeOnCompleted(continuation); } public void UnsafeOnCompleted(Action continuation) { parent.whenComplete = continuation; if (IsCompleted) { var action = Interlocked.Exchange(ref parent.whenComplete, null); if (action != null) { action(); } } } } } class WhenAllPromise { const int MaxCount = 4; T1 result1; T2 result2; T3 result3; T4 result4; ExceptionDispatchInfo exception; int completeCount; Action whenComplete; public WhenAllPromise(UniTask task1, UniTask task2, UniTask task3, UniTask task4) { this.completeCount = 0; this.whenComplete = null; this.result1 = default(T1); this.result2 = default(T2); this.result3 = default(T3); this.result4 = default(T4); this.exception = null; RunTask1(task1); RunTask2(task2); RunTask3(task3); RunTask4(task4); } void TryCallContinuation() { var action = Interlocked.Exchange(ref whenComplete, null); if (action != null) { action.Invoke(); } } void RunTask1(UniTask task) { if (task.IsCompleted) { try { result1 = task.Result; } catch (Exception ex) { exception = ExceptionDispatchInfo.Capture(ex); TryCallContinuation(); return; } var count = Interlocked.Increment(ref completeCount); if (count == MaxCount) { TryCallContinuation(); } } else { RunTask1Async(task).Forget(); } } async UniTaskVoid RunTask1Async(UniTask task) { try { result1 = await task; } catch (Exception ex) { exception = ExceptionDispatchInfo.Capture(ex); TryCallContinuation(); return; } var count = Interlocked.Increment(ref completeCount); if (count == MaxCount) { TryCallContinuation(); } } void RunTask2(UniTask task) { if (task.IsCompleted) { try { result2 = task.Result; } catch (Exception ex) { exception = ExceptionDispatchInfo.Capture(ex); TryCallContinuation(); return; } var count = Interlocked.Increment(ref completeCount); if (count == MaxCount) { TryCallContinuation(); } } else { RunTask2Async(task).Forget(); } } async UniTaskVoid RunTask2Async(UniTask task) { try { result2 = await task; } catch (Exception ex) { exception = ExceptionDispatchInfo.Capture(ex); TryCallContinuation(); return; } var count = Interlocked.Increment(ref completeCount); if (count == MaxCount) { TryCallContinuation(); } } void RunTask3(UniTask task) { if (task.IsCompleted) { try { result3 = task.Result; } catch (Exception ex) { exception = ExceptionDispatchInfo.Capture(ex); TryCallContinuation(); return; } var count = Interlocked.Increment(ref completeCount); if (count == MaxCount) { TryCallContinuation(); } } else { RunTask3Async(task).Forget(); } } async UniTaskVoid RunTask3Async(UniTask task) { try { result3 = await task; } catch (Exception ex) { exception = ExceptionDispatchInfo.Capture(ex); TryCallContinuation(); return; } var count = Interlocked.Increment(ref completeCount); if (count == MaxCount) { TryCallContinuation(); } } void RunTask4(UniTask task) { if (task.IsCompleted) { try { result4 = task.Result; } catch (Exception ex) { exception = ExceptionDispatchInfo.Capture(ex); TryCallContinuation(); return; } var count = Interlocked.Increment(ref completeCount); if (count == MaxCount) { TryCallContinuation(); } } else { RunTask4Async(task).Forget(); } } async UniTaskVoid RunTask4Async(UniTask task) { try { result4 = await task; } catch (Exception ex) { exception = ExceptionDispatchInfo.Capture(ex); TryCallContinuation(); return; } var count = Interlocked.Increment(ref completeCount); if (count == MaxCount) { TryCallContinuation(); } } public Awaiter GetAwaiter() { return new Awaiter(this); } public struct Awaiter : ICriticalNotifyCompletion { WhenAllPromise parent; public Awaiter(WhenAllPromise parent) { this.parent = parent; } public bool IsCompleted { get { return parent.exception != null || parent.completeCount == MaxCount; } } public (T1, T2, T3, T4) GetResult() { if (parent.exception != null) { parent.exception.Throw(); } return (parent.result1, parent.result2, parent.result3, parent.result4); } public void OnCompleted(Action continuation) { UnsafeOnCompleted(continuation); } public void UnsafeOnCompleted(Action continuation) { parent.whenComplete = continuation; if (IsCompleted) { var action = Interlocked.Exchange(ref parent.whenComplete, null); if (action != null) { action(); } } } } } class WhenAllPromise { const int MaxCount = 5; T1 result1; T2 result2; T3 result3; T4 result4; T5 result5; ExceptionDispatchInfo exception; int completeCount; Action whenComplete; public WhenAllPromise(UniTask task1, UniTask task2, UniTask task3, UniTask task4, UniTask task5) { this.completeCount = 0; this.whenComplete = null; this.result1 = default(T1); this.result2 = default(T2); this.result3 = default(T3); this.result4 = default(T4); this.result5 = default(T5); this.exception = null; RunTask1(task1); RunTask2(task2); RunTask3(task3); RunTask4(task4); RunTask5(task5); } void TryCallContinuation() { var action = Interlocked.Exchange(ref whenComplete, null); if (action != null) { action.Invoke(); } } void RunTask1(UniTask task) { if (task.IsCompleted) { try { result1 = task.Result; } catch (Exception ex) { exception = ExceptionDispatchInfo.Capture(ex); TryCallContinuation(); return; } var count = Interlocked.Increment(ref completeCount); if (count == MaxCount) { TryCallContinuation(); } } else { RunTask1Async(task).Forget(); } } async UniTaskVoid RunTask1Async(UniTask task) { try { result1 = await task; } catch (Exception ex) { exception = ExceptionDispatchInfo.Capture(ex); TryCallContinuation(); return; } var count = Interlocked.Increment(ref completeCount); if (count == MaxCount) { TryCallContinuation(); } } void RunTask2(UniTask task) { if (task.IsCompleted) { try { result2 = task.Result; } catch (Exception ex) { exception = ExceptionDispatchInfo.Capture(ex); TryCallContinuation(); return; } var count = Interlocked.Increment(ref completeCount); if (count == MaxCount) { TryCallContinuation(); } } else { RunTask2Async(task).Forget(); } } async UniTaskVoid RunTask2Async(UniTask task) { try { result2 = await task; } catch (Exception ex) { exception = ExceptionDispatchInfo.Capture(ex); TryCallContinuation(); return; } var count = Interlocked.Increment(ref completeCount); if (count == MaxCount) { TryCallContinuation(); } } void RunTask3(UniTask task) { if (task.IsCompleted) { try { result3 = task.Result; } catch (Exception ex) { exception = ExceptionDispatchInfo.Capture(ex); TryCallContinuation(); return; } var count = Interlocked.Increment(ref completeCount); if (count == MaxCount) { TryCallContinuation(); } } else { RunTask3Async(task).Forget(); } } async UniTaskVoid RunTask3Async(UniTask task) { try { result3 = await task; } catch (Exception ex) { exception = ExceptionDispatchInfo.Capture(ex); TryCallContinuation(); return; } var count = Interlocked.Increment(ref completeCount); if (count == MaxCount) { TryCallContinuation(); } } void RunTask4(UniTask task) { if (task.IsCompleted) { try { result4 = task.Result; } catch (Exception ex) { exception = ExceptionDispatchInfo.Capture(ex); TryCallContinuation(); return; } var count = Interlocked.Increment(ref completeCount); if (count == MaxCount) { TryCallContinuation(); } } else { RunTask4Async(task).Forget(); } } async UniTaskVoid RunTask4Async(UniTask task) { try { result4 = await task; } catch (Exception ex) { exception = ExceptionDispatchInfo.Capture(ex); TryCallContinuation(); return; } var count = Interlocked.Increment(ref completeCount); if (count == MaxCount) { TryCallContinuation(); } } void RunTask5(UniTask task) { if (task.IsCompleted) { try { result5 = task.Result; } catch (Exception ex) { exception = ExceptionDispatchInfo.Capture(ex); TryCallContinuation(); return; } var count = Interlocked.Increment(ref completeCount); if (count == MaxCount) { TryCallContinuation(); } } else { RunTask5Async(task).Forget(); } } async UniTaskVoid RunTask5Async(UniTask task) { try { result5 = await task; } catch (Exception ex) { exception = ExceptionDispatchInfo.Capture(ex); TryCallContinuation(); return; } var count = Interlocked.Increment(ref completeCount); if (count == MaxCount) { TryCallContinuation(); } } public Awaiter GetAwaiter() { return new Awaiter(this); } public struct Awaiter : ICriticalNotifyCompletion { WhenAllPromise parent; public Awaiter(WhenAllPromise parent) { this.parent = parent; } public bool IsCompleted { get { return parent.exception != null || parent.completeCount == MaxCount; } } public (T1, T2, T3, T4, T5) GetResult() { if (parent.exception != null) { parent.exception.Throw(); } return (parent.result1, parent.result2, parent.result3, parent.result4, parent.result5); } public void OnCompleted(Action continuation) { UnsafeOnCompleted(continuation); } public void UnsafeOnCompleted(Action continuation) { parent.whenComplete = continuation; if (IsCompleted) { var action = Interlocked.Exchange(ref parent.whenComplete, null); if (action != null) { action(); } } } } } class WhenAllPromise { const int MaxCount = 6; T1 result1; T2 result2; T3 result3; T4 result4; T5 result5; T6 result6; ExceptionDispatchInfo exception; int completeCount; Action whenComplete; public WhenAllPromise(UniTask task1, UniTask task2, UniTask task3, UniTask task4, UniTask task5, UniTask task6) { this.completeCount = 0; this.whenComplete = null; this.result1 = default(T1); this.result2 = default(T2); this.result3 = default(T3); this.result4 = default(T4); this.result5 = default(T5); this.result6 = default(T6); this.exception = null; RunTask1(task1); RunTask2(task2); RunTask3(task3); RunTask4(task4); RunTask5(task5); RunTask6(task6); } void TryCallContinuation() { var action = Interlocked.Exchange(ref whenComplete, null); if (action != null) { action.Invoke(); } } void RunTask1(UniTask task) { if (task.IsCompleted) { try { result1 = task.Result; } catch (Exception ex) { exception = ExceptionDispatchInfo.Capture(ex); TryCallContinuation(); return; } var count = Interlocked.Increment(ref completeCount); if (count == MaxCount) { TryCallContinuation(); } } else { RunTask1Async(task).Forget(); } } async UniTaskVoid RunTask1Async(UniTask task) { try { result1 = await task; } catch (Exception ex) { exception = ExceptionDispatchInfo.Capture(ex); TryCallContinuation(); return; } var count = Interlocked.Increment(ref completeCount); if (count == MaxCount) { TryCallContinuation(); } } void RunTask2(UniTask task) { if (task.IsCompleted) { try { result2 = task.Result; } catch (Exception ex) { exception = ExceptionDispatchInfo.Capture(ex); TryCallContinuation(); return; } var count = Interlocked.Increment(ref completeCount); if (count == MaxCount) { TryCallContinuation(); } } else { RunTask2Async(task).Forget(); } } async UniTaskVoid RunTask2Async(UniTask task) { try { result2 = await task; } catch (Exception ex) { exception = ExceptionDispatchInfo.Capture(ex); TryCallContinuation(); return; } var count = Interlocked.Increment(ref completeCount); if (count == MaxCount) { TryCallContinuation(); } } void RunTask3(UniTask task) { if (task.IsCompleted) { try { result3 = task.Result; } catch (Exception ex) { exception = ExceptionDispatchInfo.Capture(ex); TryCallContinuation(); return; } var count = Interlocked.Increment(ref completeCount); if (count == MaxCount) { TryCallContinuation(); } } else { RunTask3Async(task).Forget(); } } async UniTaskVoid RunTask3Async(UniTask task) { try { result3 = await task; } catch (Exception ex) { exception = ExceptionDispatchInfo.Capture(ex); TryCallContinuation(); return; } var count = Interlocked.Increment(ref completeCount); if (count == MaxCount) { TryCallContinuation(); } } void RunTask4(UniTask task) { if (task.IsCompleted) { try { result4 = task.Result; } catch (Exception ex) { exception = ExceptionDispatchInfo.Capture(ex); TryCallContinuation(); return; } var count = Interlocked.Increment(ref completeCount); if (count == MaxCount) { TryCallContinuation(); } } else { RunTask4Async(task).Forget(); } } async UniTaskVoid RunTask4Async(UniTask task) { try { result4 = await task; } catch (Exception ex) { exception = ExceptionDispatchInfo.Capture(ex); TryCallContinuation(); return; } var count = Interlocked.Increment(ref completeCount); if (count == MaxCount) { TryCallContinuation(); } } void RunTask5(UniTask task) { if (task.IsCompleted) { try { result5 = task.Result; } catch (Exception ex) { exception = ExceptionDispatchInfo.Capture(ex); TryCallContinuation(); return; } var count = Interlocked.Increment(ref completeCount); if (count == MaxCount) { TryCallContinuation(); } } else { RunTask5Async(task).Forget(); } } async UniTaskVoid RunTask5Async(UniTask task) { try { result5 = await task; } catch (Exception ex) { exception = ExceptionDispatchInfo.Capture(ex); TryCallContinuation(); return; } var count = Interlocked.Increment(ref completeCount); if (count == MaxCount) { TryCallContinuation(); } } void RunTask6(UniTask task) { if (task.IsCompleted) { try { result6 = task.Result; } catch (Exception ex) { exception = ExceptionDispatchInfo.Capture(ex); TryCallContinuation(); return; } var count = Interlocked.Increment(ref completeCount); if (count == MaxCount) { TryCallContinuation(); } } else { RunTask6Async(task).Forget(); } } async UniTaskVoid RunTask6Async(UniTask task) { try { result6 = await task; } catch (Exception ex) { exception = ExceptionDispatchInfo.Capture(ex); TryCallContinuation(); return; } var count = Interlocked.Increment(ref completeCount); if (count == MaxCount) { TryCallContinuation(); } } public Awaiter GetAwaiter() { return new Awaiter(this); } public struct Awaiter : ICriticalNotifyCompletion { WhenAllPromise parent; public Awaiter(WhenAllPromise parent) { this.parent = parent; } public bool IsCompleted { get { return parent.exception != null || parent.completeCount == MaxCount; } } public (T1, T2, T3, T4, T5, T6) GetResult() { if (parent.exception != null) { parent.exception.Throw(); } return (parent.result1, parent.result2, parent.result3, parent.result4, parent.result5, parent.result6); } public void OnCompleted(Action continuation) { UnsafeOnCompleted(continuation); } public void UnsafeOnCompleted(Action continuation) { parent.whenComplete = continuation; if (IsCompleted) { var action = Interlocked.Exchange(ref parent.whenComplete, null); if (action != null) { action(); } } } } } class WhenAllPromise { const int MaxCount = 7; T1 result1; T2 result2; T3 result3; T4 result4; T5 result5; T6 result6; T7 result7; ExceptionDispatchInfo exception; int completeCount; Action whenComplete; public WhenAllPromise(UniTask task1, UniTask task2, UniTask task3, UniTask task4, UniTask task5, UniTask task6, UniTask task7) { this.completeCount = 0; this.whenComplete = null; this.result1 = default(T1); this.result2 = default(T2); this.result3 = default(T3); this.result4 = default(T4); this.result5 = default(T5); this.result6 = default(T6); this.result7 = default(T7); this.exception = null; RunTask1(task1); RunTask2(task2); RunTask3(task3); RunTask4(task4); RunTask5(task5); RunTask6(task6); RunTask7(task7); } void TryCallContinuation() { var action = Interlocked.Exchange(ref whenComplete, null); if (action != null) { action.Invoke(); } } void RunTask1(UniTask task) { if (task.IsCompleted) { try { result1 = task.Result; } catch (Exception ex) { exception = ExceptionDispatchInfo.Capture(ex); TryCallContinuation(); return; } var count = Interlocked.Increment(ref completeCount); if (count == MaxCount) { TryCallContinuation(); } } else { RunTask1Async(task).Forget(); } } async UniTaskVoid RunTask1Async(UniTask task) { try { result1 = await task; } catch (Exception ex) { exception = ExceptionDispatchInfo.Capture(ex); TryCallContinuation(); return; } var count = Interlocked.Increment(ref completeCount); if (count == MaxCount) { TryCallContinuation(); } } void RunTask2(UniTask task) { if (task.IsCompleted) { try { result2 = task.Result; } catch (Exception ex) { exception = ExceptionDispatchInfo.Capture(ex); TryCallContinuation(); return; } var count = Interlocked.Increment(ref completeCount); if (count == MaxCount) { TryCallContinuation(); } } else { RunTask2Async(task).Forget(); } } async UniTaskVoid RunTask2Async(UniTask task) { try { result2 = await task; } catch (Exception ex) { exception = ExceptionDispatchInfo.Capture(ex); TryCallContinuation(); return; } var count = Interlocked.Increment(ref completeCount); if (count == MaxCount) { TryCallContinuation(); } } void RunTask3(UniTask task) { if (task.IsCompleted) { try { result3 = task.Result; } catch (Exception ex) { exception = ExceptionDispatchInfo.Capture(ex); TryCallContinuation(); return; } var count = Interlocked.Increment(ref completeCount); if (count == MaxCount) { TryCallContinuation(); } } else { RunTask3Async(task).Forget(); } } async UniTaskVoid RunTask3Async(UniTask task) { try { result3 = await task; } catch (Exception ex) { exception = ExceptionDispatchInfo.Capture(ex); TryCallContinuation(); return; } var count = Interlocked.Increment(ref completeCount); if (count == MaxCount) { TryCallContinuation(); } } void RunTask4(UniTask task) { if (task.IsCompleted) { try { result4 = task.Result; } catch (Exception ex) { exception = ExceptionDispatchInfo.Capture(ex); TryCallContinuation(); return; } var count = Interlocked.Increment(ref completeCount); if (count == MaxCount) { TryCallContinuation(); } } else { RunTask4Async(task).Forget(); } } async UniTaskVoid RunTask4Async(UniTask task) { try { result4 = await task; } catch (Exception ex) { exception = ExceptionDispatchInfo.Capture(ex); TryCallContinuation(); return; } var count = Interlocked.Increment(ref completeCount); if (count == MaxCount) { TryCallContinuation(); } } void RunTask5(UniTask task) { if (task.IsCompleted) { try { result5 = task.Result; } catch (Exception ex) { exception = ExceptionDispatchInfo.Capture(ex); TryCallContinuation(); return; } var count = Interlocked.Increment(ref completeCount); if (count == MaxCount) { TryCallContinuation(); } } else { RunTask5Async(task).Forget(); } } async UniTaskVoid RunTask5Async(UniTask task) { try { result5 = await task; } catch (Exception ex) { exception = ExceptionDispatchInfo.Capture(ex); TryCallContinuation(); return; } var count = Interlocked.Increment(ref completeCount); if (count == MaxCount) { TryCallContinuation(); } } void RunTask6(UniTask task) { if (task.IsCompleted) { try { result6 = task.Result; } catch (Exception ex) { exception = ExceptionDispatchInfo.Capture(ex); TryCallContinuation(); return; } var count = Interlocked.Increment(ref completeCount); if (count == MaxCount) { TryCallContinuation(); } } else { RunTask6Async(task).Forget(); } } async UniTaskVoid RunTask6Async(UniTask task) { try { result6 = await task; } catch (Exception ex) { exception = ExceptionDispatchInfo.Capture(ex); TryCallContinuation(); return; } var count = Interlocked.Increment(ref completeCount); if (count == MaxCount) { TryCallContinuation(); } } void RunTask7(UniTask task) { if (task.IsCompleted) { try { result7 = task.Result; } catch (Exception ex) { exception = ExceptionDispatchInfo.Capture(ex); TryCallContinuation(); return; } var count = Interlocked.Increment(ref completeCount); if (count == MaxCount) { TryCallContinuation(); } } else { RunTask7Async(task).Forget(); } } async UniTaskVoid RunTask7Async(UniTask task) { try { result7 = await task; } catch (Exception ex) { exception = ExceptionDispatchInfo.Capture(ex); TryCallContinuation(); return; } var count = Interlocked.Increment(ref completeCount); if (count == MaxCount) { TryCallContinuation(); } } public Awaiter GetAwaiter() { return new Awaiter(this); } public struct Awaiter : ICriticalNotifyCompletion { WhenAllPromise parent; public Awaiter(WhenAllPromise parent) { this.parent = parent; } public bool IsCompleted { get { return parent.exception != null || parent.completeCount == MaxCount; } } public (T1, T2, T3, T4, T5, T6, T7) GetResult() { if (parent.exception != null) { parent.exception.Throw(); } return (parent.result1, parent.result2, parent.result3, parent.result4, parent.result5, parent.result6, parent.result7); } public void OnCompleted(Action continuation) { UnsafeOnCompleted(continuation); } public void UnsafeOnCompleted(Action continuation) { parent.whenComplete = continuation; if (IsCompleted) { var action = Interlocked.Exchange(ref parent.whenComplete, null); if (action != null) { action(); } } } } } } } #endif