はじめに
UniTask.WhenAll
を利用することで全てのTask
が終了するまで待つことができます。
// 全てのTaskが終わるまで待つ await UniTask.WhenAll(UniTask.Delay(1), UniTask.Delay(2), UniTask.Delay(3));
実はこれはいくつか書き方があるので、それを紹介したいと思います。
書き方
配列、IEnumerable
、Tuple
をawait
しても同様の処理を実現できます。
var task1 = UniTask.Delay(1); var task2 = UniTask.Delay(2); var task3 = UniTask.Delay(3); // パターン1 (UniTask.WhenAllを使う) await UniTask.WhenAll(task1, task2, task3); // パターン2 (this UniTask[] tasks) await new[] { task1, task2, task3 }; // パターン3 (this IEnumerable<UniTask> tasks) await new List<UniTask> { task1, task2, task3 }; // パターン4 (Tupleを利用したパターン) await (task1, task2, task3);
ただアロケーション的な観点でいうとTuple
を利用する方が優秀なはず(要調査)なので、それを積極的に利用するといいでしょう。
実現しているコード
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member using System.Collections.Generic; namespace Cysharp.Threading.Tasks { public static partial class UniTaskExtensions { // shorthand of WhenAll public static UniTask.Awaiter GetAwaiter(this UniTask[] tasks) { return UniTask.WhenAll(tasks).GetAwaiter(); } public static UniTask.Awaiter GetAwaiter(this IEnumerable<UniTask> tasks) { return UniTask.WhenAll(tasks).GetAwaiter(); } public static UniTask<T[]>.Awaiter GetAwaiter<T>(this UniTask<T>[] tasks) { return UniTask.WhenAll(tasks).GetAwaiter(); } public static UniTask<T[]>.Awaiter GetAwaiter<T>(this IEnumerable<UniTask<T>> tasks) { return UniTask.WhenAll(tasks).GetAwaiter(); } public static UniTask<(T1, T2)>.Awaiter GetAwaiter<T1, T2>(this (UniTask<T1> task1, UniTask<T2> task2) tasks) { return UniTask.WhenAll(tasks.Item1, tasks.Item2).GetAwaiter(); } // ... public static UniTask<(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15)>.Awaiter GetAwaiter<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15>(this (UniTask<T1> task1, UniTask<T2> task2, UniTask<T3> task3, UniTask<T4> task4, UniTask<T5> task5, UniTask<T6> task6, UniTask<T7> task7, UniTask<T8> task8, UniTask<T9> task9, UniTask<T10> task10, UniTask<T11> task11, UniTask<T12> task12, UniTask<T13> task13, UniTask<T14> task14, UniTask<T15> task15) tasks) { return UniTask.WhenAll(tasks.Item1, tasks.Item2, tasks.Item3, tasks.Item4, tasks.Item5, tasks.Item6, tasks.Item7, tasks.Item8, tasks.Item9, tasks.Item10, tasks.Item11, tasks.Item12, tasks.Item13, tasks.Item14, tasks.Item15).GetAwaiter(); } public static UniTask.Awaiter GetAwaiter(this (UniTask task1, UniTask task2) tasks) { return UniTask.WhenAll(tasks.Item1, tasks.Item2).GetAwaiter(); } // ..... public static UniTask.Awaiter GetAwaiter(this (UniTask task1, UniTask task2, UniTask task3, UniTask task4, UniTask task5, UniTask task6, UniTask task7, UniTask task8, UniTask task9, UniTask task10, UniTask task11, UniTask task12, UniTask task13, UniTask task14, UniTask task15) tasks) { return UniTask.WhenAll(tasks.Item1, tasks.Item2, tasks.Item3, tasks.Item4, tasks.Item5, tasks.Item6, tasks.Item7, tasks.Item8, tasks.Item9, tasks.Item10, tasks.Item11, tasks.Item12, tasks.Item13, tasks.Item14, tasks.Item15).GetAwaiter(); } } }