ChannelFactory.Close VS IClientChannel.Close - PullRequest
32 голосов
/ 15 мая 2009

Рассмотрим следующий код, типичный для многих примеров ChannelFactory:

WSHttpBinding myBinding = new WSHttpBinding();
EndpointAddress myEndpoint = new EndpointAddress(
   ConfigurationSettings.AppSettings["HelloWorldServiceURL"]);  

ChannelFactory<IHelloWorldService> myChannelFactory = 
   new ChannelFactory<IHelloWorldService>(myBinding, myEndpoint);

IHelloWorldService proxy = myChannelFactory.CreateChannel();
((IClientChannel)proxy).Open();
HelloWorldDataContract dc = proxy.SayHello();
((IClientChannel)proxy).Close();

Обратите внимание, что при вызове proxy.Open () состояние канала и состояние ChannelFactory становятся «открытыми». Когда вызывается proxy.Close (), состояние канала становится «закрытым», но состояние ChannelFactory остается «Открытым».

Следует ли также закрывать ChannelFactory? Я не вижу этого во многих примерах. Также, если возможно, объясните разницу между открытым каналом и открытым заводом-изготовителем канала.

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

Ответы [ 4 ]

19 голосов
/ 15 февраля 2011

Я нашел основной ответ неточным, поэтому я отвечаю здесь.

Очевидно, что Microsoft создала абсолютный беспорядок из каналов и фабрик и клиентов. Документация также не помогает, так как они, кажется, существуют только для того, чтобы скрыть беспорядок, поэтому мне пришлось прибегнуть к тестированию.

Из-за проблем с производительностью, связанных с некэшируемыми каналами, в v3.5 была изменена реализация, чтобы устранить их, и добавлено кэширование, но это только усложнило проблему.

Точка канала в ChannelFactory фактически не отличается от канала, используемого IClientChannel при создании канала с использованием ChannelFactory.CreateChannel(). Это все тот же горшок. Поверь мне нет? Попробуйте:

ChannelFactory<IService> factory = new ChannelFactory<IService>();
// ...
IService service = factory.CreateChannel();
factory.Close();
service.DoIt() // Throws object disposed exception

Так что на самом деле внутренне это все тот же канал. Лично я начал распоряжаться фабриками каналов, а не клиентскими каналами, и не сталкивался с какими-либо проблемами. Я также попытался сделать это в цикле с созданием 100000 клиентских каналов и только закрытием ChannelFactory.

14 голосов
/ 15 мая 2009

Как вы знаете, ChannelFactory создает клиентский канал на основе конфигурации. Возможно, вы захотите создать несколько клиентских каналов из существующей фабрики (к той же конечной точке, что и заблокированная). Если вы закончили использовать фабрику для создания каналов, нет причин не закрывать ее.

Но почему вы хотите оставить его открытым? Вот интересная статья о клиентах WCF , в которой говорится:

Проверка значения System.ServiceModel.ICommunicationObject.State собственность является условием гонки и не рекомендуется определять, повторно использовать или закрыть канал.

Вместо того, чтобы повторно использовать канал, вы можете просто создать новый с фабрикой каналов. Подробнее об архитектуре клиента здесь .

4 голосов
/ 14 сентября 2011

Другой вариант - использовать статический метод CreateChannel: msdn.microsoft.com / EN-US / библиотека / aa344556.aspx

1 голос
/ 25 октября 2018

Ответ уже здесь, но он распределен по нескольким комментариям и ответам и не совсем ясен, поэтому мой ответ.

Нужно ли закрывать ChannelFactory так же, как Channel?

Нет. Если вы хотите создать несколько каналов из каждого ChannelFactory, вам следует избавиться от ChannelFactory, который будет располагать всеми каналами, которые он создал для вас.

Если вы хотите создать один канал для каждой пары (конечная точка, привязка), вы должны использовать эту статическую функцию : ChannelFactory<ServiceType>.CreateChannel(binding, endpoint) (которая устраняет проблему, поскольку не создает второй IDisposable) и вы должны избавиться от канала, который он возвращает.

Удаление как фабрики каналов, так и любого из созданных им каналов вызовет исключение ObjectDisposed.

...