코루틴은 다른 스크립트 코드와 다르게 실행됩니다. 대부분의 스크립트 코드는 단일 위치의 성능 트레이스 내, 특정 Unity 콜백 호출 아래에 나타납니다. 반면, 코루틴의 CPU 코드는 항상 트레이스의 두 곳에서 나타납니다.
코루틴의 모든 시작 코드(코루틴 메서드의 시작부터 첫 번째 yield가 나타나는 곳까지의 코드)는 트레이스에서 나타나고, 트레이스에서 코루틴이 시작됩니다. 보통 StartCoroutine
메서드가 호출되는 곳에서 나타납니다. Unity 콜백(IEnumerator
를 반환하는 Start
콜백 등)에서 생성된 코루틴은 각각의 Unity 콜백에서 최초로 나타납니다.
코루틴의 나머지 모든 코드(즉 다시 재개되는 시점에서부터 실행이 종료될 때까지의 코드)는 Unity 메인 루프에 있는 DelayedCallManager
행에 나타납니다.
왜 이러한 현상이 일어나는지 이해하려면 코루틴이 실제로 어떻게 실행되는지 생각해 보아야 합니다.
코루틴은 C# 컴파일러가 자동으로 생성한 클래스의 인스턴스에 의해 작동합니다. 이 오브젝트는 프로그래머에게 하나로 간주되는 메서드를 여러 번 호출하는 코루틴의 상태를 추적하는 데 필요합니다. 코루틴의 로컬 범위 변수는 yield
호출이 진행되는 동안 유지되어야 하기 때문에 변수는 생성된 클래스에 위치하게 되며, 코루틴이 작동되는 동안 힙에 할당된 상태로 남아 있습니다. 오브젝트는 코루틴의 내부 상태를 추적하여 yield 호출 이후에 코루틴이 재개될 때 코드의 어느 부분부터 재개할 것인지를 기억합니다.
그렇기 때문에 코루틴을 시작할 때 발생하는 메모리 사용량은 고정된 오버헤드 비용에 로컬 범위 변수의 크기를 합한 양과 동일합니다.
코루틴을 시작하는 코드는 이 오브젝트를 생성하고 호출하며, 그 이후 Unity의 DelayedCallManager
가 코루틴의 yield 조건이 만족될 때마다 다시 오브젝트를 호출합니다. 코루틴은 보통 다른 코루틴의 외부에서 시작하기 때문에 코루틴 실행 비용은 위에서 설명한 두 위치로 나뉩니다.
위 스크린샷에서 DelayedCallManager
는 PopulateCharacters
, AsyncLoad
및 LoadDatabase
를 비롯한 여러 개의 다른 코루틴을 다시 시작합니다.
가능한 경우 일련의 작업을 최대한 적은 수의 개별 코루틴으로 압축하는 것이 좋습니다. 코루틴을 중첩하면 코드 명료성을 높이고 유지관리가 용이하지만, 코루틴 추적(tracking) 오브젝트로 인해 더 많은 메모리가 소모됩니다.
코루틴이 매 프레임마다 실행되고 오래 실행되는 작업에서 이익이 되지 않는 경우, 일반적으로 코루틴을 Update
또는 LateUpdate
콜백으로 대체하면 더 쉽게 읽을 수 있습니다. 특히 오래 실행되거나 무한 루프되는 코루틴의 경우 더욱 그렇습니다.
StopCoroutine과 StopAllCoroutines를 사용하여 코루틴을 중지할 수 있습니다.
또한 SetActive(false)로 인해 연결된 게임 오브젝트가 비활성화될 때에도 코루틴이 중지됩니다. Destroy(example)
(여기서 example
은 MonoBehaviour 인스턴스)을 호출하면 OnDisable
이 즉시 트리거되고 코루틴이 처리되므로 효과적으로 중지할 수 있습니다. 마지막으로, OnDestroy
는 프레임이 끝날 때 호출됩니다.
MonoBehaviour 인스턴스에서 enabled를 false로 설정하여 MonoBehaviour를 비활성화한 경우에는 코루틴이 중지되지 않습니다.
코루틴은 스레드가 아니라는 점을 명심하십시오. 코루틴의 동기 작업은 여전히 메인 스레드에서 실행됩니다. 목표가 메인 스레드에서 소비되는 CPU 시간을 줄이는 것이라면 다른 스크립트 코드에서와 마찬가지로 코루틴의 작업 차단을 방지하는 것이 중요합니다.
코루틴은 HTTP 전송, 에셋 로드, 파일 I/O 완료 등을 기다리는 것과 같이 긴 시간을 필요로 하는 비동기 작업에 사용하는 것이 가장 유용합니다.
Did you find this page useful? Please give it a rating:
Thanks for rating this page!
What kind of problem would you like to report?
Thanks for letting us know! This page has been marked for review based on your feedback.
If you have time, you can provide more information to help us fix the problem faster.
Provide more information
You've told us this page needs code samples. If you'd like to help us further, you could provide a code sample, or tell us about what kind of code sample you'd like to see:
You've told us there are code samples on this page which don't work. If you know how to fix it, or have something better we could use instead, please let us know:
You've told us there is information missing from this page. Please tell us more about what's missing:
You've told us there is incorrect information on this page. If you know what we should change to make it correct, please tell us:
You've told us this page has unclear or confusing information. Please tell us more about what you found unclear or confusing, or let us know how we could make it clearer:
You've told us there is a spelling or grammar error on this page. Please tell us what's wrong:
You've told us this page has a problem. Please tell us more about what's wrong:
Thank you for helping to make the Unity documentation better!
Your feedback has been submitted as a ticket for our documentation team to review.
We are not able to reply to every ticket submitted.