본문 바로가기
프로그래밍/C#

비동기 메서드의 형식을 맞추기 위해서 필요한 Task.CompletedTask

by bantomak 2025. 5. 15.
반응형

Task.CompletedTask란?

Task.CompletedTask는 비동기 작업(Task)의 완료 상태를 나타낼 때 사용한다. 즉, Task.CompletedTask를 선언하면 이미 성공적으로 완료된 Task 인스턴스를 반환한다.

Task task = Task.CompletedTask;

위에 예제처럼 사용시 성공적으로 완료된 Task를 반환받는다. 즉, 아무 일도 하지 않고 즉시 완료된 Task를 얻는다.

그렇다면 이런 기능은 어디에 사용해야 하는 걸까?

비동기 메서드에서 특별히 수행할 작업이 없을 때

  • 해당 메서드는 아무 일도 하지 않지만 Task를 반환해야 하기 때문에 Task.CompletedTask를 사용했다.
  • await도 없고 비동기 작업도 없기 때문에 본래라면 같이 써야 하는 async 키워드도 불필요하다.
public Task DoNothingAsync()
{
    return Task.CompletedTask;
}
  • 아래처럼 구현하는 것도 가능하지만, 컴파일러는 async 키워드를 보고 비동기 상태 머신을 생성하기 때문에 성능 손해가 발생한다.
// 실제 비동기 작업이 없다면 async는 사용하지 말자.
public async Task DoNothingAsync()
{
    await Task.CompletedTask;
}

인터페이스 구현 시 필수 반환 형식을 맞출 때

  • 인터페이스를 상속받고 메서드를 구현할 시에 반환해야 하는 반환값이 Task라면 해당 형식에 맞춰서 구현이 돼야 한다.
    하지만 해당 함수에서 진행해야 할 작업이 없는 경우 반환값은 맞춰야 하기에 사용한다.
public interface IService
{
    Task InitializeAsync();
}

public class MyService : IService
{
    public Task InitializeAsync()
    {
        // 초기화할 작업이 없을 경우
        return Task.CompletedTask;
    }
}

Task.CompletedTask 장점

  • 성능이 좋음 : 새로운 Task를 생성하지 않고, static으로 이미 만들어진 Task를 재사용
  • GC 부담 적음 : 메모리 할당이 없고, 매번 인스턴스를 만들지 않음
  • 의도 표현 : 실제 비동기 작업이 아니라 완료된 Task 객체만 필요하다는 의도를 명확히 보여줌

댓글