Awaitable 코드 예시 레퍼런스
Solve common asynchronous programming problems with a reference of Awaitable code examples.
읽는 시간 3분최근 업데이트: 한 달 전
이 레퍼런스의 예시들은 비동기 코드를 작성할 때 발생하는 일반적인 시나리오에서 사용할 수 있는 솔루션을 보여줍니다.
Awaitable비동기적 테스트
Unity의 테스트 프레임워크는 을 유효한 테스트 반환 유형으로 인식하지 않습니다. 그러나 다음 예시는 의 구현을 사용하여 비동기 테스트를 작성하는 방법을 보여줍니다.
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 Task에서 Awaitable 래핑
.NET 래핑하여 의 몇 가지 제한 사항을 우회할 수 있습니다. 이렇게 하면 할당 비용이 발생하지만 API의 및 와 같은 메서드에 액세스할 수 있게 됩니다. 이를 위해서는 다음과 같이 커스텀 확장 메서드를 자체적으로 작성할 수 있습니다.
TaskAwaitableTaskWhenAllWhenAnyAsTask// 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; } }
결과를 여러 번 기다리기
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을 Task에 래핑할 수 있는 시나리오에 해당합니다. 이를 통해 를 여러 번 안전하게 기다릴 수 있습니다.
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; }