티스토리 뷰

C#

C#: WCF ServiceClient의 IDiaposable 구현

개태형님 2019. 4. 24. 23:42

WCF의 Client 구현시 Service참조를 하면 Proxy코드가 자동 생성된다.

이때 ServiceClient코드도 자동 생성된다.

ServiceClient는 ClientBase를 상속받으며, ClientBase는 IDisposable 인터페이스를 구현하였다.

 

그렇기 때문에 실제 ServiceClient는 아래와 같은 코드로 사용이 가능하다.

(※ ServiceClient는 사용후 필히 Close() 처리를 해줘야 함)

using (var client = new ServiceClient())
{
    client.Hello();
}

 

using 블럭으로 감싼 ServiceClient는 ClientBase에서 구현된 Dispose 함수 내부에서 client.Close()를 호출해준다.

여기서 문제는.. client.Close()를 실행중 에러가 발생할 경우 최종 Abort() 처리가 되지 않는다는 것이다.

이를 해결하기 위해 자동 생성된 ServiceClient class를 partial class로 나눈 후 추가적으로 IDisposable을 구현해줘야 한다.

 

// IDisposable을 구현한 ServiceClient partial class
public partial class ServiceClient : IDisposable
{
    private bool _isDisposed;

    public void Dispose()
    {
        ServiceClientUtilities.Dispose(this, ref _isDisposed);
    }

    ~ServiceClient()
    {
        Dispose();
    }
}

// 재사용 가능한 ServiceClient Dispose Util class
public static class ServiceClientUtilities
{
    public static void Dispose(ICommunicationObject service, ref bool isDisposed)
    {
        if (isDisposed) return;

        try
        {
            if (service.State == CommunicationState.Faulted)
            {
                service.Abort();
            }
            else
            {
                try
                {
                    service.Close();
                }
                catch (Exception closeException)
                {
                    try
                    {
                        service.Abort();
                    }
                    catch (Exception abortException)
                    {
                        throw new AggregateException(closeException, abortException);
                    }
                    throw;
                }
            }
        }
        finally
        {
            isDisposed = true;
        }
    }
}

 

출처 : https://blog.rsuter.com/correctly-handle-wcf-clients-life-cycle-simple-way/

댓글
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday