はじめに
今回はValueTask
に対してWhenAny
, WhenAll
, Lazy
を適応できるようにするValueTaskSupplement
について紹介したいと思います。
またLazy
(AsyncLazy
)に関しては、私自身ちゃんと理解できていなくこの記事には書かないので注意してください。
ちゃんと理解できたらまた別記事で書きたいと思っています。
テスト環境
- Unity2022.22.1f1
- ValueTaskSupplement v1.1.0 (
2023/2/9
時点ではv1.1.0
が最新)
依存先
- System.Buffers v4.5.0 or later
- System.Memory v4.5.3 or later
- System.Threading.Tasks.Extensions v4.5.3 or later
インストール
以下の操作を行います。
nuget.org
からDownload package
を選択、valuetasksupplement.1.1.0.nupkg
をダウンロード- 拡張子を
.zip
に変更し解凍 valuetasksupplement.1.1.0/lib/netstandard2.0/ValueTaskSupplement.dll
をUnity
のPlugins
にインポート
また依存先のライブラリを入れなくても、Unity2022.22.1f1
では動作しました。
使い方
private async void Start() { // ----------------------- // ------- WhenAll ------- // ----------------------- var (x0, y0) = await ValueTaskEx.WhenAll(HogeAsync(), FugaAsync()); Debug.Log($"x0 : {x0}, y0 : {y0}"); // x0 : 1, y0 : 2 // 以下のような書き方もできます var result = await new[] {HogeAsync(), FugaAsync()}; Debug.Log($"result[0] : {result[0]}, result[1] : {result[1]}"); // result[0] : 1, result[1] : 2 // 以下の書き方も var (x1, y1) = await (HogeAsync(), FugaAsync()); Debug.Log($"x1 : {x1}, y1 : {y1}"); // x1 : 1, y1 : 2 // ----------------------- // ------- WhenAny ------- // ----------------------- var (winArgumentIndex, a, b) = await ValueTaskEx.WhenAny(HogeAsync(), FugaAsync()); Debug.Log(winArgumentIndex == 0 ? $"a : {a}" : $"b : {b}"); // a : 1 // Timeoutなどで活用できるようなメソッド // ValueTask<(bool hasResultLeft, T result)> WhenAny<T>(ValueTask<T> left, Task right); var (index, left) = await ValueTaskEx.WhenAny(HogeAsync(), Task.Delay(TimeSpan.FromSeconds(1))); Debug.Log($"index : {index}, left : {left}"); // index : True, left : 1 // ValueTask<(bool hasResultLeft, T result)> WhenAny<T>(ValueTask<T> left, ValueTask right); var (index1, left1) = await ValueTaskEx.WhenAny(HogeAsync(), DelayAsync()); Debug.Log($"index1 : {index1}, left1 : {left1}"); // index1 : True, left1 : 1 } private static async ValueTask<int> HogeAsync() { await Task.Delay(TimeSpan.FromSeconds(0.5f)); return 1; } private static async ValueTask<int> FugaAsync() { await Task.Delay(TimeSpan.FromSeconds(2)); return 2; } private static async ValueTask DelayAsync() { if (DateTime.Now.Second == 0) return; await Task.Delay(TimeSpan.FromSeconds(1)); }
めちゃめちゃ便利です。