Version: Unity 6.0 (6000.0)
언어 : 한국어
Awaitable 작업 완료 및 지속
잡 시스템

Awaitable 코드 예시 레퍼런스

이 레퍼런스의 예시들은 비동기 코드를 작성할 때 발생하는 일반적인 시나리오에서 사용할 수 있는 Awaitable 솔루션을 보여줍니다.

비동기적 테스트

Unity의 테스트 프레임워크Awaitable을 유효한 테스트 반환 유형으로 인식하지 않습니다. 그러나 다음 예시는 IEnumeratorAwaitable 구현을 사용하여 비동기 테스트를 작성하는 방법을 보여줍니다.

[UnityTest]
public IEnumerator SomeAsyncTest(){
    async Awaitable TestImplementation(){
        // test something with async / await support here
    };
    return TestImplementation();
}

프레임 코루틴

Awaitable 클래스에서 프레임 관련 비동기 메서드를 사용하여 반복자 기반 코루틴을 대체하는 비동기 Unity 코루틴을 생성할 수 있습니다.

async 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은 델리게이트가 true를 평가할 때까지 코루틴 실행을 일시 중지합니다. 취소 토큰을 사용하여 조건이 변경될 때까지 기다리게 함으로써 Awaitable 반환 비동기 메서드와 동등한 동작을 만들 수 있습니다.

public static async AwaitableUntil(Func<bool> condition, CancellationTokenSource cancellationToken)
{
   while(!condition()){
     cancellationToken.ThrowIfCancellationRequested();
     await Awaitable.NextFrameAsync();
  }
}

이후에 다음과 같이 취소 토큰을 전달할 수 있습니다.

cancellationTokenSource = new CancellationTokenSource();
currentTask = AwaitableUntil(myCondition, cancellationTokenSource.Token);

비동기식으로 리소스 로드

메인 스레드를 차단하지 않도록 비동기식 리소스 로드 작업을 await할 수 있습니다.

public 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;
}

합성

동일한 방법으로 여러 개의 서로 다른 await 호환 유형을 await할 수 있습니다.

public async Awaitable Start()
{
    await CallSomeThirdPartyAPIReturningDotnetTask();
    await Awaitable.NextFrameAsync();
    await SceneManager.LoadSceneAsync("my-scene");
    await SomeUserCodeReturningAwaitable();
    ...
}

.NET Task에서 Awaitable 래핑

.NET Task 래핑하여 Awaitable의 몇 가지 제한 사항을 우회할 수 있습니다. 이렇게 하면 할당 비용이 발생하지만 Task API의 WhenAllWhenAny와 같은 메서드에 액세스할 수 있게 됩니다. 이를 위해서는 다음과 같이 커스텀 AsTask 확장 메서드를 자체적으로 작성할 수 있습니다.

// Implement custom AsTask extension methods to wrap Awaitable in Task
public 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;
        }
    }

결과를 여러 번 기다리기

AwaitableTask의 주요 차이점은 할당을 줄이기 위해 Awaitable 객체를 풀링하는 것입니다. 결과를 여러 번 완료하는 Awaitable 반환 메서드를 안전하게 await할 수는 없습니다. 이는 원본 Awaitable 오브젝트는 반환된 이후에 풀로 돌아가기 때문입니다.

안전하지 않은 버전

다음 코드는 안전하지 않으며 예외와 멈춤 현상을 발생시킵니다.

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 Task
public 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;
 }

추가 리소스

Awaitable 작업 완료 및 지속
잡 시스템
Copyright © 2023 Unity Technologies
优美缔软件(上海)有限公司 版权所有
"Unity"、Unity 徽标及其他 Unity 商标是 Unity Technologies 或其附属机构在美国及其他地区的商标或注册商标。其他名称或品牌是其各自所有者的商标。
公安部备案号:
31010902002961