[C#] WebClient Timeout 설정 방법

Wookoa 2024. 10. 20.

WebClient Timeout 설정 방법
WebClient Timeout 설정 방법

머리말

  C# 환경에서 개발 업무를 수행하던 중 HTTP 웹 통신으로 특정 서버와 통신하는 하는 경우가 발생했다. 웹 객체의 종류는 많지만 지원하는 함수와 프로퍼티는 모두 제각각이라 사용할 때마다 적당한 검색을 통해 개발을 수행한다. 최대한 간결하고 가볍게 구성하기 위해 고민을 많이 해봤지만 본 포스팅에서 소개하는 방법이 최선의 방법이라 생각된다. 본 포스팅에서는 WebClient 객체에서 Timeout 프로퍼티를 설정하는 방법에 대해서 소개한다.

WebClient 객체에서 Timeout 설정 방법

  웹을 이용하는 클라이언트에서 주로 사용되는 기능을 모아놓은 라이브러리가 WebClient 객체다. 그렇기 때문에 HttpWebRequest, HttpWebResponse 클래스를 직접 사용하는 것보다 무겁다. 이유는 WebClient 클래스는 HttpWebRequest, HttpWebResponse 클래스를 내부적으로 사용하고 있는 Wrapper 클래스기 때문이다. WebClient 보다 세밀한 제어를 원할 경우 HttpWebRequest, HttpWebResponse 클래스를 사용하면 된다. 하지만 WebClient 객체를 사용하는 가장 큰 이유는 제공되는 함수가 다양하기 사용하기 때문에 매우 간결한 코딩으로 파일 다운로드와 같은 기능을 구현할 수 있기 때문이다.

  하지만 WebClient 객체에서는 Timeout 프로퍼티를 기본적으로 제공하지 않으며, 필요하다면 개발자가 직접 기능을 오버라이드(override)해서 구현해야 된다. 본 포스팅에서는 WebRequest 객체의 GetWebRequest 함수를 오버라이드 하는 방법을 소개할 텐데, Microsoft 공식 문서에서 제공하는 가이드다.

  Microsoft 공식 문서에 따르면 WebClient 객체는 System.ComponentModel.Component 객체를 상속받는다. 하지만 WebRequest 객체의 함수를 오버라이드 해서 구현하라는 가이드가 이해되지 않는다. 잘 이해가 되지 않아 Microsoft 공식 문서를 찾아보니 아래의 그림과 같은 상관관계를 찾을 수 있었다. 자세히 설명하자면 WebClient 객체는 내부적으로 HttpWebRequest/HttpWebResponse 객체를 사용하는데, HttpWebRequest/HttpWebResponse 객체는 WebRequest 객체를 상속받아서 생성되었다. 그렇기 때문에 WebClient 객체에서 사용하는 HttpWebRequest 객체의 GetWebRequest 함수는 WebRequest 객체에 정의된 함수를 오버라이드 해서 사용할 수 있게 되며, 의문이었던 WebClient 상속 클래스인 Component 객체는 전혀 무관하다는 결론이다.

WebRequest 객체를 상속받는 이유
WebRequest 객체를 상속받는 이유

  아래의 소스는 TimoutWebClient 이름으로 클래스를 생성해서 WebClient 객체를 상속받는다. WebClient 객체에서 내부적으로 사용되는 GetWebRequest 함수를 Timeout 설정이 가능하도록 오버라이드 한다. TimoutWebClient 객체를 생성할 때 Timeout 값으로 설정할 Micro-Second 값을 받는다.

using System;
using System.Net;

namespace Wookoa
{
    class TimeoutWebClient : WebClient
    {
        int timeout = 0;

        public TimeoutWebClient(int _timeout)
        {
            timeout = _timeout;
        }

        protected override WebRequest GetWebRequest(Uri address)
        {
            WebRequest request = base.GetWebRequest(address);
            request.Timeout = timeout;

            return request;
        }
    }
}

  위와 같이 클래스를 생성한 뒤, 객체를 생성할 때 아래와 같이 인자 값을 넘겨주면 WebClient 객체에서도 Timeout 설정이 가능하게 된다. 아래의 예제는 1500 마이크로초를 타임아웃으로 설정했다.

public MainWindow()
{
    ...
    ...
    TimeoutWebClient client = new TimeoutWebClient(1500);
    string str = client.DownloadString(new Uri("https://www.wookoa.com"));
    ...
    ...
}

꼬리말

  결과만 놓고 보자면 매우 간단한 소스이며 복사/붙여 넣기만으로 충분히 구현이 가능한 기능이다. 하지만 객체의 상속관계를 알고 코딩하는 것과 큰 차이가 있기에 본 포스팅에서 자세히 설명했다. 개발 스타일이 콤팩트하다면 위와 같이 함수를 오버라이드 해서 사용하기보다는 WebRequest 직접 핸들링하면서 필요한 기능만 간결하게 구현해서 사용하는 방법도 좋다. 물론 기능상의 큰 차이점은 없지만 WebClient 객체를 충분히 활용하지 않는다면 분명 리소스 낭비는 발생할 것이다.

  추가로 Microsoft 공식 문에서는 WebClient, HttpWebRequest, HttpWebResponse 객체 사용을 지양하라는 중요 안내 문구가 표시된다. 향후 닷넷 프레임워크에서는 지원하지 않을 움직임으로 생각된다. 그에 대한 대안으로 HttpClient 객체를 권장하고 있는데 추후 포스팅에는 권장되는 HttpClient 객체를 활용해서 파일 다운로드를 구현하는 방법을 소개할 계획이다. 이로써 C# 언어에서 http 통신의 Timeout을 설정하는 방법에 대해서 소개한 본 포스팅은 마무리를 짓도록 한다.

인기있는 글

소중한 댓글 (0)