응용프로그램의 성능, 확장성 향상의 이유로 비동기 프로그래밍 방식이 자주 사용되곤 한다.
닷넷 프레임워크에서도 스레드(전용 스레드 or 스레드 풀) 혹은 비동기 프로그래밍 모델을 활용해 비동기 작업을 수행할 수 있다.
여기서 비동기 프로그래밍 모델을 APM(Asynchronous Programming Model)이라 칭하는데, 닷넷 프레임워크의 I/O 관련 클래스들은 모두 이 모델을 이용할 수 있도록 설계되어 있다.
I/O를 위한 동기 방식 메서드 이름과 동일한 BeginXXX, EndXXX 쌍의 비동기 메서드가 제공되는데, 다음과 같은 I/O 클래스들에서 이를 활용할 수 있다.
System.Net.WebRequest
System.IO.Stream
System.Data.SqlClient.SqlCommand
System.Net.Sockets.Socket
필자의 회사에서 운영하는 시스템도 많은 곳에시 비동기 패턴을 이용하고 있다. 그 중 한 예로, 여러 시스템이 혼재되어 하나의 서비스를 완성하는데 이때 각 시스템의 구간 안정성 현황을 파악하기 위해 원격 서버로 로그를 전송하는 로직이 비동기로 구현되어 있다.
그런데 이 로그는 실제 비지니스와는 무관한 부분이라(크로스 커팅 기능), 종속성을 배제하기 위해 로그 서버는 단방향 서비스로 구현하고 이를 소비하는 클라이언트는 APM 방식으로 구현되어 있다.
그런데 문제는 로그 저장의 성공/실패에 관심을 두지 않는다는 것이, 비동기 호출 후 콜백을 받지 않는 구현으로 이어졌다는 것이다. 즉 BeginXXX만 호출하고 EndXXX는 구현하지 않은 것이다.
사용량이 많지 않는 환경에서는 이것이 그리 큰 문제가 되지는 않는다. 하지만 필자의 시스템 환경은 Server to Server 방식으로 로그서버를 소비하는 클라이언트 역시 서버 응용프로그램이며 이 서버 응용프로그램에 수많은 요청이 동시에 몰리면 메모리 누수는 점차 누적되어 프로그램이 심각한 타격을 입을 수 있다는 것이다.
다음의 글에서 밝히고 있듯이, 비동기 호출 결과에 관심이 없다고 해서 EndXXX를 호출하지 않아도 된다는 것은 아니니 주의해야 할 일이다.
첫째 CLR은 이 리소스들을 EndXXX 메서드가 호출될 때까지 유지시킨다. 그리고 EndXXX 메서드가 결국 호출되지 않는다면 이 리소스들은 계속 반환되지 않다가 프로세스가 종료될 때에 반환된다. 둘째, 비동기 작업을 초기화할 때 실제로 개발자는이 작업이 성공할 것인지 알지 못한다. 성공유무를 확실하게 확인하는 방법은 EndXXX 메서드를 호출하는 것이며, 이 메서드를 호출함으로써 결과 값이 정상적으로 반환되는지 아니면 예외가 발생하는지 알 수 있다.
- CLR via C#
'.NET Framework' 카테고리의 다른 글
Optimizing IIS Performance (8) | 2013.11.07 |
---|---|
클라이언트의 동시 연결 수(maxconnection) (6) | 2013.11.06 |
OAuth 2.0 Flow (6) | 2013.09.05 |
Custom Configuration (1875) | 2013.08.26 |
간단한 C# 문법 Quiz (5) | 2013.07.11 |