2025. 7. 17. 01:22ㆍUnity, C# 프로그래밍
키워드
Task (대기 가능한 객체)
- 내가 만든 MyTask 라는 클래스가 있을 때, MyTask를 await 하려면 MyTask 클래스가 MyTaskAwaiter(가명)를 반환하는 GetAwaiter() 를 구현해야 함.
- MyTask를 async 메서드의 반환형으로 사용하고 싶다면 AsyncMethodBuilder 지원이 필요함.
TaskAwaiter (대기자)
- ICriticalNotifyCompletion 인터페이스를 구현해야 함.
- 결과를 반환하는 GetResult() 함수를 구현해야 함.
- 작업이 완료되었는지 알 수 있는 IsCompleted 프로퍼티를 구현해야 함.
ICriticalNofifyCompletion
- TaskAwaiter 구현 시 사용 작업이 완료된 후 실행될 콜백 예약에 대해 구현.
- 기본적으로 OnCompleted() 및 UnsafeOnCompleted() 에서 넘어오는 continuation 델리게이트를 비동기 작업이 완료되었을 때 호출하도록 해 주면 됨.
- 만약 SynchronizationContext 및 TaskScheduler 지원이 필요하다면 OnCompleted() 및 UnsafeOnCompleted()에서 작업을 연계해 주어야 함.
- 여기서 구현하는 OnCompleted 및 UnsafeOnCompleted 는 AsyncMethodBuilder의 구현체에서 사용하게 됨.
AsyncMethodBuilder
- 특정 Task 타입에 대한 async/await 상태 머신 구현 지원.
- 내가 구현한 MyTask 가 async 함수의 반환형으로 사용될 경우 구현해야 함.
async / await
- await 구문은 GetAwaiter() 를 구현하는 클래스만이 가능함.
- async 메서드의 반환형으로 사용될 객체는 AsyncMethodBuilder 지원이 필요함.
(ex. public async MyTask<T> Method() 라는 함수가 있다면 이때 MyTask<T> 객체가 AsyncMethodBuilder 지원 필요)
SynchronizationContext / TaskScheduler
- 작업 continue시 사용됨.
- 하나의 작업이 끝나고 다음 작업을 연계할 때 어느 위치에서 작업이 실행될 지 결정 (스레드 풀로 넘기거나 등등)
- System.Threading.Tasks.Task 및 ValueTask 는 위의 구현이 모두 되어있음.
- System.Threading.Tasks.Task 객체에 있는 ConfigureAwait(false) 사용 시 Awaiter를 ConfiguredTaskAwaitable 로 사용하게 되고, SynchronizationContext 및 TaskScheduler 를 무시하고 작업을 예약하게 된다.
- 유니티는 메인 스레드의 SynchronizationContext를 UnitySynchronizationContext로 재정의해서 여기로 예약되는 모든 continuation들을 메인스레드에서 폴링한다.
따라서 await 를 사용해도 이후 코드들이 다시 메인 스레드에서 실행되게 된다.
- 유니티에서 async 함수를 쓰고, 그 함수 내에서 작업 await시 이후 작업이 UnitySynchronizationContext에 의해서 메인 스레드에 예약되는데,
해당 Task를 동기 메서드인 Result 나 Wait() 사용 시 메인 스레드가 블로킹 되며 예약된 작업이 실행되지 못해 데드락이 걸릴 수 있다.
이걸 방지하려면 아예 작업 시작을 Task.Run() 으로 하거나 ConfigureAwait(false)로 사용하면 된다.
- 위의 코드들은 디컴파일러로 확인 시 실제로 어떻게 적용되는지 확인 가능.
'Unity, C# 프로그래밍' 카테고리의 다른 글
| 유니티 Color Hex 값 편리하게 사용하기 (2) | 2024.02.28 |
|---|---|
| 유니티 에셋 번들 빌드 시간 단축 사례 (0) | 2024.02.01 |
| 유니티 C# 개발 시 사용하기 좋은 툴 및 사이트 (2) | 2024.01.03 |
| C#의 람다 (익명 함수) 사용 시 주의할 점 (2) | 2024.01.03 |
| XML 데이터 로딩 최적화 사례 (1) | 2023.12.28 |