WCF Закрыть соединение, используя анонимные методы - PullRequest
3 голосов
/ 28 августа 2009

В нашем проекте мы делаем вызовы WCF, используя следующий код.

// In generated Proxy we have..
public static ICustomer Customer
{
 get
  {
    ChannelFactory<ICustomer> factory = new ChannelFactory<ICustomer>("Customer");
    factory.Endpoint.Behaviors.Add((System.ServiceModel.Description.IEndpointBehavior)new ClientMessageInjector());
    ICustomer channel = factory.CreateChannel();
    return channel;
  }
}

и у нас есть класс Service Proxy, который имеет такие методы, как

public static Datatable GetCustomerDetails(int id)
{
  return Services.Customer.GetCustomerDetails(id);
} 

public static void .SaveCustomerDetails (int id)
{
  Services.Customer.SaveCustomerDetails(id) ;
}

и т. Д. ... которые мы используем для деловых звонков.

Недавно мы обнаружили, что нам нужно «закрыть» соединение wcf, и мы пытаемся найти способ сделать это, не прося наших разработчиков слишком сильно менять свой код.

Пожалуйста, предоставьте нам несколько предложений, которые помогут нам достичь этой цели

Ответы [ 6 ]

6 голосов
/ 28 августа 2009

Принятая «лучшая практика» для этого случая будет выглядеть примерно так:

// create your client
ICustomer channel = CreateCustomerClient();

try
{
   // use it
   channel.GetCustomerDetails() ....

   (more calls)

   // close it
   channel.Close();
}
catch(CommunicationException commEx)
{
   // a CommunicationException probably indicates something went wrong 
   // when closing the channel --> abort it
   channel.Abort();
}

Как правило, поскольку канал также реализует «IDisposable», у вас может возникнуть желание просто поместить его в

using(ICustomer channel = CreateCustomerChannel()) 
{
   // use it
}
Блок

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

У нашего модератора Марка Гравелла есть интересное сообщение в блоге (не (не используйте)) по теме, с элегантным решением проблемы.

Марк

1 голос
/ 29 августа 2009

Вы также пропускаете ChannelFactory<T> объектов в текущем подходе. Вы должны закрыть это тоже. Если вы используете статические CreateChannel методы на ChannelFactory<T>, вы получите автоматическое закрытие для фабрики при закрытии клиента, что поможет решить эту проблему. К сожалению, статическая перегрузка CreateChannel(string endpointConfigurationName) защищена, поэтому для ее вызова вам потребуется подкласс ChannelFactory<T>. (Это может быть не так уж плохо в целом.)

Теперь, если вы хотите «автоматически закрыть» поведение канала и используете сессионный контракт (SessionMode = SessionMode.Required), вы можете пометить все свои сервисные операции «IsInitiating = true, IsTerminating = true» в атрибуте [OperationContract]. Обратите внимание, что это не позволит вам когда-либо вызывать более одной операции, используя один и тот же прокси-сервер ICustomer. Это может быть самый простой вариант, если он вам доступен.

Что касается вашего общего подхода, то не считается хорошим проектом для свойства выполнять слишком много работы, особенно когда оно включает в себя создание новых (дорогих) объектов и попадание в сеть. Прокси WCF являются хорошими абстракциями и выглядят как простые реализации интерфейса, но они не являются без сохранения состояния и должны управляться соответствующим образом.

0 голосов
/ 30 августа 2009

Не создавайте новую фабрику каналов каждый раз, когда вы создаете канал. Это ужасно с точки зрения производительности!

0 голосов
/ 28 августа 2009

К сожалению, мы используем сгенерированные методы Proxy, которые возвращают канал, и мы используем его во многих местах. Так что я подумал, что будет какой-то способ «расширить» канал и закрыть соединение после выполнения вызова (используя методы расширения) .

0 голосов
/ 28 августа 2009

Информация в этом вопросе также может быть полезна.

0 голосов
/ 28 августа 2009

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

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