WCF: ServiceClient + Dispose - PullRequest
       3

WCF: ServiceClient + Dispose

0 голосов
/ 21 февраля 2011

Это то, что я понимаю из того, почему нам нужно реализовать наш собственный класс-оболочку для serviceClients (пожалуйста, исправьте меня, если я ошибаюсь):

Цель ловли исключения в методе Dispose () заключается в том, что .Close () может выдать "CommunicationException" или «TimeoutException» - и для предотвращения связь повесить вы ловите те два исключения для использования .Abort (), который изменит состояние объект связи закрыт immediatley. - это не сделало бы смысл позволять исключению быть необработанный, потому что необязательные вызовы чтобы методы уже были сделаны так как мы находимся в части Dispose (), и поэтому было бы странно бросить исключение, когда работа на самом деле сделано как надо.

Но почему:

public class ServiceClientWrapper<TServiceType> : IDisposable
{
    public TServiceType Channel { get; private set; }
    private readonly ChannelFactory<TServiceType> _channelFactory;

    public ServiceClientWrapper(string endpoint)
    {
        _channelFactory = new ChannelFactory<TServiceType>(endpoint);
        Channel = _channelFactory.CreateChannel();
        ((IChannel)Channel).Open();
    }

    #region Implementation of IDisposable

    public void Dispose()
    {
        try
        {
            ((IChannel)Channel).Close();
        }
        catch (CommunicationException ex)
        {
            ((IChannel)Channel).Abort();
        }
        catch (TimeoutException ex)
        {
            ((IChannel)Channel).Abort();
        }
        catch (Exception)
        {
            ((IChannel)Channel).Abort();
            throw;
        }
    }

    #endregion
}

Когда вы можете сделать:

public class ServiceClientWrapper<TServiceType> : IDisposable
{
    public TServiceType Channel { get; private set; }
    private readonly ChannelFactory<TServiceType> _channelFactory;

    public ServiceClientWrapper(string endpoint)
    {
        _channelFactory = new ChannelFactory<TServiceType>(endpoint);
        Channel = _channelFactory.CreateChannel();
        ((IChannel)Channel).Open();
    }

    #region Implementation of IDisposable

    public void Dispose()
    {
        ((IChannel)Channel).Abort();
    }

    #endregion
}

Согласно MSDN, .Close() и .Abort() изменят состояние объекта связи на «Закрыто»?

Ответы [ 2 ]

3 голосов
/ 22 февраля 2011

Дело в том, что Close () будет стремиться корректно закрыть весь канал связи, включая любое закрывающее рукопожатие, требуемое протоколом связи, тогда как Abort () - грубое и жестокое разрушение стека каналов на стороне клиента безпопытайтесь сообщить закрытие должным образом другой стороне.Поэтому прерывание может привести к тому, что ресурсы на стороне сервера будут по-прежнему связаны с соединениями, которые не будут использоваться в дальнейшем.

Поэтому мы всегда хотим выполнить Close, если это возможно, но нам нужно обрабатывать ситуации, когда что-то настолько нарушено, что попытказакрытие приведет к дальнейшему исключению.

2 голосов
/ 22 февраля 2011

Метод закрытия:

http://msdn.microsoft.com/en-us/library/ms405496.aspx

Этот метод заставляет CommunicationObject плавно переходить из любого состояния, кроме закрытого, в закрытое состояние. Метод Close позволяет завершить любую незаконченную работу перед возвратом. Например, завершите отправку любых буферизованных сообщений.

метод отмены Делает то же самое изящно или как указано в спецификации сразу. Это НЕ завершит ничего, что еще происходит ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...