Awaitable のコード例リファレンス
Solve common asynchronous programming problems with a reference of Awaitable code examples.
読み終わるまでの所要時間 6 分最終更新 1ヶ月前
このリファレンスの例は、非同期コードの記述時に経験する一般的なシナリオに対する、 での解決策を示しています。
Awaitable非同期テスト
Unity の Test Framework は、 を有効なテストの戻り値の型として認識しません。しかし、以下の例は、 の 実装を使用して非同期テストを記述する方法を示しています。
AwaitableIEnumeratorAwaitable[UnityTest]public IEnumerator SomeAsyncTest(){ async Awaitable TestImplementation(){ // test something with async / await support here }; return TestImplementation();}
フレームコルーチン
Awaitableasync Awaitable SampleSchedulingJobsForNextFrame(){ // Wait until end of frame to avoid competing over resources with other Unity subsystems await Awaitable.EndOfFrameAsync(); var jobHandle = ScheduleSomethingWithJobSystem(); // Let the job execute while the next frame starts await Awaitable.NextFrameAsync(); jobHandle.Complete(); // Use results of computation}JobHandle ScheduleSomethingWithJobSystem(){ ...}
条件付き待機
イテレーターベースのコルーチンでは、デリゲートが を評価するまで、WaitUntil はコルーチンの実行をサスペンドします。キャンセルトークンを使用して条件が変更されるまでメソッドを待機させることで、 を返す非同期メソッドと同等の動作を作成できます。
trueAwaitablepublic static async AwaitableUntil(Func<bool> condition, CancellationTokenSource cancellationToken){ while(!condition()){ cancellationToken.ThrowIfCancellationRequested(); await Awaitable.NextFrameAsync(); }}
その後、以下のようにキャンセルトークンを渡すことができます。
cancellationTokenSource = new CancellationTokenSource();currentTask = AwaitableUntil(myCondition, cancellationTokenSource.Token);
リソースの非同期ロード
非同期のリソースロード操作を して、メインスレッドをブロックしないようにすることができます。
awaitpublic async Awaitable Start(){ // Load texture resource asynchronously var operation = Resources.LoadAsync("my-texture"); // Return control to the main thread while the resource loads await operation; var texture = operation.asset as Texture2D;}
合成
同じメソッド内で複数の異なる に互換性のある型を できます。
awaitawaitpublic async Awaitable Start(){ await CallSomeThirdPartyAPIReturningDotnetTask(); await Awaitable.NextFrameAsync(); await SceneManager.LoadSceneAsync("my-scene"); await SomeUserCodeReturningAwaitable(); ...}
.NET タスクでの Awaitable のラッピング
AwaitableTaskTaskWhenAllWhenAnyAsTask// Implement custom AsTask extension methods to wrap Awaitable in Taskpublic static class AwaitableExtensions { public static async Task AsTask(this Awaitable a) { await a; } public static async Task<T> AsTask<T>(this Awaitable<T> a) { return await a; } }
結果を複数回 Await する
AwaitableTaskAwaitableAwaitableawaitAwaitable安全ではないバージョン
以下のコードは 安全ではなく、例外とデッドロックの原因になります。
async Awaitable Bar(){ var taskWithResult = SomeAwaitableReturningFunction(); var awaitOnce = await taskWithResult; // Do something // The following will cause errors because at this point taskWithResult has already been pooled back var awaitTwice = await taskWithResult; }
安全なバージョン
これは、割り当ての手間をかけて、タスクで Awaitable をラップ できるシナリオの 1 つです。こうすると、 は複数回安全に await できます。
Task// Implement custom AsTask extension methods to wrap Awaitable in Taskpublic static class AwaitableExtensions { public static async Task AsTask(this Awaitable a) { await a; } public static async Task<T> AsTask<T>(this Awaitable<T> a) { return await a; } }async Awaitable Bar(){ var taskWithResult = SomeAwaitableReturningFunction(); // Wrap the returned Awaitable in a Task var taskWithResultAsTask = taskWithResult.AsTask(); // The task can now be safely awaited multiple times, at the cost of allocating var awaitOnce = await taskWithResultAsTask; // Do something var awaitTwice = await taskWithResultAsTask; }