C# using 지시문의 기본 용도
C#에서 using 지시문(using directive)은 네임스페이스(namespace)를 가져오거나, 네임스페이스 및 타입에 별칭(alias)을 부여할 때 사용합니다. 일반적으로 소스 파일의 맨 위, 모든 선언부보다 먼저 위치해야 합니다.
using System; using System.IO; using WinForms = global::System.Windows.Forms; using WinButton = WinForms::Button;
using 문이 보장하는 Dispose() 자동 호출
using 문(using statement)은 객체를 생성하고 메서드나 속성을 호출하는 과정에서 예외(exception)가 발생하더라도 Dispose() 메서드가 반드시 실행되도록 보장합니다. Dispose()는 IDisposable 인터페이스에 정의된 메서드로, 사용자 지정 가비지 컬렉션(Custom Garbage Collection)을 구현하는 핵심 요소입니다.
예를 들어 데이터베이스 작업(INSERT, UPDATE, DELETE) 수행 중 예외가 발생하는 상황을 생각해 보겠습니다. 이때 using 블록을 사용했다면 연결이 자동으로 종료되므로, 명시적으로 Close() 메서드를 호출할 필요가 없습니다.
연결 풀링(Connection Pooling)이란?
using 문의 또 다른 중요한 장점은 연결 풀링에 기여한다는 점입니다. .NET의 연결 풀링은 데이터베이스 연결을 매번 열고 닫는 비효율적인 작업을 제거하여 응용 프로그램 성능을 크게 향상시키는 메커니즘입니다.
연결 풀링의 동작 방식은 다음과 같습니다.
- 연결이 더 이상 필요하지 않으면 해당 연결 객체는 완전히 파괴되지 않고 풀(pool)로 반환되어 재사용을 대기합니다.
- 응용 프로그램이 새 데이터베이스 연결을 요청하면, 매번 새 연결을 생성하는 대신 풀에 있는 기존 연결 객체를 꺼내 사용합니다.
- 연결 생성·해제에 드는 오버헤드가 줄어들어 전체 응용 프로그램의 성능이 개선됩니다.
using 문을 사용하면 코드 블록이 끝나는 시점에 연결 객체가 자동으로 연결 풀에 반환됩니다. 따라서 개발자가 Close()와 Dispose() 메서드를 직접 호출할 필요가 없습니다.
using 문 기본 예제
using (Stream input = File.OpenRead(filename)) {
...
}
데이터베이스 연결 예제(SqlConnection)
string connString = "Data Source=localhost;Integrated Security=SSPI;Initial Catalog=Northwind;";
using (SqlConnection conn = new SqlConnection(connString)) {
SqlCommand cmd = conn.CreateCommand();
cmd.CommandText = "SELECT CustomerId, CompanyName FROM Customers";
conn.Open();
using (SqlDataReader dr = cmd.ExecuteReader()) {
while (dr.Read())
Console.WriteLine("{0}\t{1}", dr.GetString(0), dr.GetString(1));
}
}
위 코드에는 연결을 닫는 Close() 호출이 전혀 없습니다. 그럼에도 불구하고 연결은 자동으로 종료되는데, using 블록의 범위를 벗어나는 순간 conn.Close()가 자동으로 호출되기 때문입니다. 내부의 SqlDataReader 객체 역시 using 문으로 감싸져 있어 자동으로 해제됩니다.
또한 코드 실행 중 예외가 발생하더라도 using 문이 연결을 확실하게 닫아주기 때문에, 리소스 누수(resource leak) 걱정 없이 안전하고 깔끔한 데이터베이스 코드를 작성할 수 있습니다.