Task Asynchronous Programming에 대해서 Microsoft에서 소개한 글을 읽고 간단하게 정리해 보았다. 국문도있지만, 기계 번역이라 이해하기 쉽지가 않다.
비동기 프로그래밍
규칙적인 시간 관계가 없는 것으로, 임의의 사상의 출현을 말하고 프로그램 실행에서는 명령순서 예측이 불가능한 것 - 비동기
비동기 프로그래밍은 비동기적으로 실행되는 부분을 포함한 프로그램을 구성하는 것이다. 비동기적 실행이라는 것은 실행의 종료시점과 실행주체가 동기화 되지않고 실행되는 것이다. 쉽게 설명하자면, 정확히 언제 끝날지 모르는 일이다.
비동기 프로그래밍의 대표적인 경험은 Web일 것이다. Javascript는 비동기 콜백이 엄청나게 많다. 너무 많아서 콜백 지옥이라고도 표현한다.ㅋ 익숙해지면 익숙한대로 요령것 프로그래밍이 가능하다.ㅎ
타이젠 네이티브 어플리케이션 개발할 때도 콜백을 정말 많이 사용했는데, 확실히 다루기 까다롭다. 개발자를 힘들게하는 것 중 하나다. 그런데, .NET에서 너무 쉽게 비동기 프로그래밍을 할 수 있다는 사실에 놀랐다. 그래서 글을 쓰게 되었다.
async 와 await
The async and await keywords in C# are the heart of async programming. task-asynchronous-programming-model
간단하게 생각하면 정말 간단하다. Javascript ES8 async
, await
과 같은 느낌으로 사용하면 된다. 읽기 편하고, 쓰기 편하라고 만든만큼 참 쉽다. 읽기도, 쓰기도!
내가 여기서 설명을 붙이면 쓰레기를 양산하는 것 밖에 안되는 느낌일 정도로 좋은 설명과 예시가 이미 풍부하다. 절대 귀찮아서 그런거 아님!
thread
여기까지 접했을 때 thread에 대한 의문이 안 생기면 이상한거다. .NET runtime에서 처리해준다고 하지만, 어떻게? 비용은 어떻게되고? 개발자라면 당연히 궁금해야 할 내용이다.
The async and await keywords don't cause additional threads to be created. Async methods don't require multithreading because an async method doesn't run on its own thread.
별도의 쓰레드를 따로 만들지도 않고, 멀티 쓰레딩이 필요하지도 않다고 한다. Task.Run
으로 별도의 쓰레드를 만드는 것보다 훨씬 편리하고, 고질적인 race conditions 문제에 머리를 싸매도 되지 않는다! 이게 핵심이다! 그 동안 쓰레드 관리하느라 thread pool 만들고, race conditions 관리하느라 뮤텍스랑 세마포를 끼고 살았던, 그럼에도 불구하고 늘 이슈가 생겼던 아픔이 한방에 싸악~!
그럼에도 궁금한 것이, 그러면 무조건 같은 쓰레드에서 다시 실행시켜 준다는 것인가? 마치 자바스크립트의 Promise
처럼 single-thread로 동작하면서 task queue를 사용하는 것인가? 궁금증을 해소하기 위해 stackoverflow를 찾았다.
async and await are single threaded Really?를 보면, 나와 같은 호기심과 의심을 갖은 사람이 많이 있다는 것을 알 수 있는데, 여기에 아주 적절한 포스트로 댓글 Async and Await 이 달려있다.
the awaitable will capture the current “context” and later apply it to the remainder of the async method.
내용을 간단하게 설명하자면, await
은 awaitable
을 전달인자로 받는 단항 연산자이다. awaitable
은 context를 가지고 있다가 사용한다. UI thread라면, UI Context를 캡쳐하고 있다가 사용되므로 UI 구현에 큰 도움이 될 것이다. 하지만, UI Context가 아니라면?
- If you’re on a UI thread, then it’s a UI context.
- If you’re responding to an ASP.NET request, then it’s an ASP.NET request context.
- Otherwise, it’s usually a thread pool context.
UI Context가 아니라면? 그냥 thread pool에서 await
이후의 코드가 실행될 것이다! 조금 맥이 빠진다. 항상 같은 쓰레드로 다시 돌아가는 것은 아니니까 신경써서 사용해야 한다. Javascript와는 다르다! 그래도 적당한 곳에서 꽤 유용하게 사용할 수 있을 것 같다.
마치며
관련 가이드나 소개글이 엄청 기대감을 갖게 만들어서, 그 동안 멀티 쓰레딩 관리하느라 힘들었던 고통이 사라질 수 있다는 생각에 잠시나마 들뜬 마음으로 관련된 글들을 읽었다. 하지만, 모든 곳에 사용할 수는 없을 것 같고, 멀티 쓰레딩 프로그램은 여전히 많은 고민과 함께 조심스레 만들어야 한다.
물위에 오리가 유유히 거닐지만, 오리발은 쉴틈 없이 움직인다는 사실을 또 한번 새삼 떠올리게 된다. 개발 환경이나 언어는 점점 쉬워지지만, 그 아래 기술은 여전히 복잡하고 심지어 일부는 더 복잡해지고 있다. 내가 물 속 사정에 신경 끌 수 있는 입장이 아니라서...;;
이번에 놀란 것은 이미 아주 오래전에 소개되었다는 점과 .NET은 국문 커뮤니티와 블로그도 많다는 것이다. 역시 세상은 넓고, 고수는 많다.
'기술 이야기' 카테고리의 다른 글
C# .NET IDisposable을 이용한 Dispose pattern과 SafeHandle (0) | 2020.05.26 |
---|---|
오픈소스로 개발하면 좋은점 - 1 (0) | 2020.05.19 |
Android Jetpack은 API가 아니다 (0) | 2020.05.11 |
Shared Library가 링크되는 과정 (0) | 2020.03.23 |
한국, 인터넷과 스마트폰 접근율 세계 1위 (0) | 2018.07.27 |
토큰 기반 인증 간단 정리 Token based Authentication (1) | 2018.05.02 |
AWS CloudFront와 S3로 Private Content 전달 방법 (0) | 2018.04.24 |
댓글