WCF: Безопасно ли переопределять метод Dispose клиента, используя частичный класс? - PullRequest
3 голосов
/ 09 апреля 2010

Я бы хотел переопределить метод Dispose сгенерированного прокси (ClientBase) из-за того, что утилизация прокси вызывает Close и может выдать исключение при сбое канала.

Единственный способ, которым я пришел, - это создать частичный класс для моего сгенерированного прокси, сделать его наследником от IDisposable:

 public partial class MyServiceProxy : IDisposable
    {
        #region IDisposable Members

        public void Dispose()
        {
            if (State != System.ServiceModel.CommunicationState.Faulted)
                Close();
            else
                Abort();
        }

        #endregion
    }

Я провел некоторый тест, и мой метод Dispose действительно вызывается.

Видите ли вы какие-либо проблемы с этой стратегией?

Кроме того, мне не нравится тот факт, что мне придется создавать этот частичный класс для каждого сгенерированного прокси.

Было бы хорошо, если бы я мог заставить мой прокси наследовать от базового класса ...

Ответы [ 2 ]

2 голосов
/ 09 апреля 2010

С этим проблем нет. Такая настройка кода, сгенерированного дизайнером, - это как раз та функция, которую должны предоставлять частичные классы, и это один из рекомендуемых способов борьбы с нарушенной реализацией IDisposable в ClientBase.

Что касается необходимости повторной реализации этого кода для каждого клиента WCF - к сожалению, да, если вы захотите использовать шаблон IDisposable с ними. Вы можете извлечь блок if/else в служебный метод, но вам все равно придется создать частичный класс для каждого и переопределить Dispose.

Поскольку вышеприведенное довольно утомительно, многие люди предпочитают вместо этого использовать Service Proxy Helper , поскольку он не требует написания нового кода.

Я использую слегка измененную версию, сам:

public static class Service<TProxy>
    where TProxy : ICommunicationObject, IDisposable, new()
{
    public static void Using(Action<TProxy> action)
    {
        TProxy proxy = new TProxy();
        bool success = false;
        try
        {
            action(proxy);
            proxy.Close();
            success = true;
        }
        finally
        {
            if (!success)
            {
                proxy.Abort();
            }
        }
    }
}

Что позволяет писать такой код:

Service<MyServiceClient>.Using(svc => svc.PerformOperation());

Или:

Service<MyServiceClient>.Using(svc =>
{
    var result = svc.PerformOperation();
    ProcessResult(result);
});

Примечание. Создание прокси WCF обходится дорого, поэтому вы, как правило, стараетесь поддерживать их как можно дольше, а не создавать и утилизировать их каждые несколько секунд (или больше). Это предназначено для клиентов, которые редко используются.

1 голос
/ 09 апреля 2010

Переопределение метода Dispose () - совершенно правильная стратегия.

В ответах на этот вопрос есть еще несколько вариантов: Как лучше всего обойтись для клиента WCF `using` block проблема?

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