2022년 9월 7일 수요일

C# Async/Await Task 속도가 느릴 때 (TaskCompletionSource)

고전적인 개발 방법으로는 작업이 끝났는지 확인하기 위해서

작업 내용을 확인하는 루프를 만들어서 확인을 하는데


나는 이걸 mysql 풀링에 사용했었다.


그러니까 지금 사용 가능한 mysql 연결이 있는지를 task 에서

루프 돌면서 확인하는 방식으로 만들었던 것이다.


그런데 처음에 async/await task 방식이 문제라고 잘못 생각했던 것이

cpu 점유율을 너무 많이 먹었던 것이다.


ram이나 다른 리소스는 문제가 되지 않았다.

그저 cpu 점유율만 높았다. 그래서 이거 계속 써야 하나 싶었다.

그런데 써보니까 async 에서의 순차 실행이 참 편한 부분이 많았고

해결책을 찾아보니 내 코딩 스타일과 맞지 않았던 것이다.


루프 돌면서 쉬는 mysql 연결을 찾는 코드가 문제였는데

전체 확인하고나서 Task.Yield() 해서 한펌 쉬는 코드를 해놨는데

이게 유니티에서의 1프레임 단위가 아니었던 것이다.

결국 mysql 커넥션이 전부 사용중일때 많은 task 들이 yield를 하면서

루프를 도는데 이 텀이 너무 짧다보니 거의 무한루프(?) 돌듯이 계속 체크하면서

cpu를 다 먹었었다.


그래서 task 관련 공부를 더 했고 해결책을 찾았는데 그게

TaskCompletionSource였다.

값이 맞춰질때까지 대기하는 것이기 때문에 mysql을 다 쓴 후 반환하는 코드에서

mysql 연결 인덱스를 맞춰주니 yield를 사용할 필요가 없어서 cpu 사용율이

획기적으로 내려갔다.


사실 이건 내 코딩 스타일이 오래되서 그런거 같다. 하여간 문제는 해결이 되었고

이제 cpu 점유율 문제는 사라졌다.


C# Async/Await Task 속도가 느릴 때 (TaskCompletionSource)

고전적인 개발 방법으로는 작업이 끝났는지 확인하기 위해서 작업 내용을 확인하는 루프를 만들어서 확인을 하는데 나는 이걸 mysql 풀링에 사용했었다. 그러니까 지금 사용 가능한 mysql 연결이 있는지를 task 에서 루프 돌면서 확인하는 방식으로 만...