비동기의 이점은 반응성이지 성능 향상이 아니기 때문에, 작업을 비동기로 처리하든, 동기로 처리하든, 작업량 자체가 많다면 시스템 자원 소비도 많아 지는 물리적 법칙은 비동기 코드의 관습으로 극복할 수 있을까하는 의문이 있습니다.
SemaphoreSlim 을 적용하면, 시스템의 전체 througput 을 제한하는 것과 비슷한 것이라, 병목 현상 때문에 오히려 성능이 저하될 것 같은데, 반대라니 놀랍네요.
그리고, 예외의 처리 관습과 비동기 코드 관습은 별개로 인식되어야 할 것 같습니다.
예를 들면, async void 는 return 을 기다리는 호출자가 명확하지 않을 때 혹은 return 자체를 신경 쓰지 않을 때, 대표적으로 이벤트를 (비동기로) 처리하는 때입니다. 이런 정황에서는, 이벤트 핸들러가 throw 한다는 것은 오히려 더 이상한 것이죠.
그것 보다는, 비동기와 상관 없이, “기대된” 예외는 즉시 에러로 처리 - 예방을 하든, catch를 해서 진짜 "예외"와 구분해야 하는 것이 더 중요할 것 같습니다.
var address = // 주소를 나타내는 문자열
// address 값을 검증하여 에러 예방
if (Uri.IsWellFormedUriString(address, UriKind.Absolute) is false)
{
// return
}
// GetAsync 의 예외는 문서에 나와 있기 때문에 기대된 예외 => catch
try {
using var http = new HttpClient();
var response = await http.GetAsync(address, token);
}
catch( // catches
asyncawait가 비용증가로 이어질 수 있다는 것은 사실인지 좀 더 확인해봐야 될 것 같네요.
이 부분은 누군가 아시는 분이 계시면 그럴 가능성에 대해서 설명해 주시면 좋을 것 같습니다.
글의 내용은 비용 문제를 말하기 보다는 asyncawait의 잘못 된 사용사례를 보여주고 모범 사례를 보여주는 글 같습니다.
@al6uiz 님 말씀 처럼 UI가 없는 서버 환경에서 ConfigureAwait(false)는 성능 향상을 기대할 수 없다고 봐야 될 것 같습니다. Semaphore를 사용하는 솔루션은 왜 넣었는지 모를만큼 잘 이해가 안가네요??
최대 동시성(아마 CPU 코어의 개수) 만큼만 코드를 진행시키려는 의도 같은데 어차피 엄청 많은 Task를 돌려 쓰레드풀에서 더 이상 가져가 쓸 쓰레드가 없으면 쓰레드를 받을 때가지 기다리는 건 마찬가지 일 것 같아서요..
그리고 I/O Bound 작업이 많을 때는 비동기가 실제로 성능 향상에 큰 도움이 됩니다.
실제로 싱글 스레드 기반인 Node를 사용하는 언어의 경우도 싱글 스레드이지만 I/O Bound 작업에 대해서는 비동기 작업을 하면 성능이 향상됩니다.
hi, semaphore is grate solution when you have limited resources and possible huge amount of actions.
For instance you have thousands ids and you need to perform some action for each in your db. With semaphore you can limit concurent actions to not overwhelming your db
제한된 자원(DB)이 있을 때 rate limit에 걸리게 하지 않기위해라고 합니다!
답변을 들으니 이해가 되긴 하네요.