説明
AsTask
を実行すると以下の挙動になります。
この ValueTask でラップされる Task オブジェクト (存在する場合)、または、結果を表す新しい Task オブジェクト。
ValueTask.AsTask メソッド (System.Threading.Tasks) | Microsoft Learn
相変わらず公式ドキュメントはカタコトですが、
Task
のインスタンスが存在する(非同期処理)場合はそのままTask
を返すTask
のインスタンスが存在しない(同期処理)場合は結果を格納した新しいTask
を生成して返す
ということだと思います。
ValueTask
の良さを潰しているといったらそうな気もしますが、Task
に変換する必要があるなら仕方がないでしょう。
private async void Start() { // ValueTask<TResult> // ValueTaskはWhenAllやWhenAnyが適応できない ValueTask<bool> valueTask = SampleAsync(); // 同期処理のため既に終わっている Debug.Log(valueTask.IsCompleted); // true Debug.Log(valueTask.IsCompletedSuccessfully); // true Debug.Log(valueTask.Result); // true bool result = await valueTask; Debug.Log(valueTask.IsCompleted); // true Debug.Log(valueTask.IsCompletedSuccessfully); // true Debug.Log(valueTask.Result); // true Debug.Log(result); // true // AsTask Task<bool> task = SampleAsync().AsTask(); // 同期処理のため既に終わっている // Task<TResult>が生成されていた場合はそれを返し、存在しない場合は新しいTask<TResult>を生成する Debug.Log(task.IsCompleted); // true Debug.Log(task.IsCompletedSuccessfully); // true Debug.Log(task.Result); // true bool result2 = await task; Debug.Log(task.IsCompleted); // true Debug.Log(task.IsCompletedSuccessfully); // true Debug.Log(task.Result); // true Debug.Log(result2); } private async ValueTask<bool> SampleAsync() => true; private async ValueTask<bool> Sample2Async() => true;
ちなみにですが、Unity
にはValueTask
に対してWhenAll
やWhenAny
を適応できるようにしたValueTaskSupplement
というライブラリがあったりします。