[C# 동시성 프로그래밍] 완료한 작업 반환
- C#/C# 문법
- 2022. 5. 12. 18:05
참고
- C# 동시성 프로그래밍
문제점
- 비동기 시그니처를 사용해서 동기 메서드를 구현해야 합니다.
- 비동기 인터페이스 또는 비동기 클래스를 상속하고 있지만 동기적으로 구현하고 싶을 때 이런 상황이 일어날 수 있습니다.
- 이런 기법은 비동기 코드를 단위 테스트하면서 비동기 인터페이스에 사용할 간단한 스텁이나 목이 필요할 때 특히 유용합니다.
해법
Task.FromResult
를 사용하면 지정한 값으로 이미 완료한Task<T>
를 새로 만들어서 반환할 수 있습니다.
interface IMyAsyncInterface
{
Task<int> GetValueAsync();
}
class MySynchronousImplementation : IMyAsyncInterface
{
public Task<int> GetValueAsync()
{
return Task.FromResult(13);
}
}
- 반환 값이 따로 없는 메서드라면 성공적으로 완료한 Task가 들어 있는 Task.CompletedTask를 사용할 수 있습니다.
interface IMyAsyncInterface
{
Task DoSomethingAsync();
}
class MySynchronousImplementation : IMyAsyncInterface
{
public Task DoSomethingAsync()
{
return Task.CompletedTask;
}
}
- Task.FromResult는 성공적인 결과로 완료한 작업만 제공합니다.
- NotImplementedException 으로 완료한 작업 등 결과가 다른 작업이 필요하면
Task.FromException
을 사용할 수 있습니다.
Task<T> NotImplementedAsync<T>()
{
return Task.FromException<T>(new NotImplementedException());
}
- 마찬가지로 전달한 CancellationToken 으로 이미 취소한 작업을 생성하는 Task.FromCanceled 도 있습니다.
Task<int> GetValueAsync(CancellationToken cancellationToken)
{
if(cancellationToken.IsCancellationRequested)
return Task.FromCanceled<int>(cancellationToekn);
return Task.FromResult(13)
}
- 동기적 구현이 실패할 가능성이 있다면 다음과 같이 예외를 잡은 뒤에 Task.FromException을 사용해서 반환해야 합니다.
interface IMyAsyncInterface
{
Task DoSomethingAsync();
}
class MySynchronousImplementation : IMyAsyncInterface
{
public Task DoSomethingAsync()
{
try
{
DoSomethingSynchronously();
return Task.CompletedTask;
}
catch(Exception ex)
{
return Task.FromException(ex);
}
}
}
정리
- 동기적인 코드를 사용해서 비동기 인터페이스를 구현하려면 모든 형태의 차단을 피애햐 합니다.
- 비동기적으로 구현할 수 있는데도 다른 작업을 차단하고 자기 작업을 완료한 뒤에 반환한다면 비동기 메서드로 이상적이지 않습니다.
- 주기적으로 같은 값을 사용해서 Task.FromResult로 작업을 만들어야 한다면 작업을 미리 만들어서 저장해 놓는 방법도 고려하길 바랍니다.
- 예를 들어 다음과 같이 결과값 0으로 Task
를 만들어 놓으면 가비지 컬렉션으로 사라질 인스턴스를 다시 만들지 않아도 항상 같은 작업 결과를 사용할 수 있습니다.
private static readonly Task<int> zeroTask = Task.FromResult(0);
Task<int> GetValueAsync()
{
return zeroTask;
}
- Task.FromResult, Task.FromException, Task.FromCanceled 는 모두 범용 형식인
TaskCompletionSource<T>
의 헬퍼 메서드이자 축약형 입니다. TaskCompletionSource<T>
는 다른 방식의 비동기 코드와 상호 운용에 유용한 하위 레벨 형식입니다.- 일반적으로 이미 완료한 작업을 반환하고 싶으면 축약형인 Task.FromResult 등을 사용해야 합니다.
728x90
'C# > C# 문법' 카테고리의 다른 글
[C# MapSter] 맵핑 객체 내부의 프로퍼티가 서로 다른 경우 (0) | 2022.05.15 |
---|---|
[C# 문법] C# JSON 데이터 Serialize, DeSerialize 하기 (0) | 2022.05.12 |
[C#] C# Mapster 사용법 (0) | 2022.05.11 |
[C# 동시성 프로그래밍] - 일정 시간 동안 일시 정지 (0) | 2022.05.08 |
[C# 동시성 프로그래밍] - 동시성 프로그래밍 개념 정리 (0) | 2022.05.07 |
이 글을 공유하기