ChannelFactory.Close VS IClientChannel.Close
Рассмотрим следующий код, который является типичным для многих примеров 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 остается "Opened".
Следует ли закрывать ChannelFactory? Кажется, я не вижу этого во многих примерах. Кроме того, если возможно, объясните разницу между открытием канала и открытием канала factory.
Кроме того, я знаю о проблеме IDisposable, поэтому, вероятно, это может быть проигнорировано ради этого вопроса, если оно не оказывает прямого влияния на ответ.
Ответы
Ответ 1
Как вы знаете, ChannelFactory создает клиентский канал на основе конфигурации. Возможно, вы захотите создать несколько клиентских каналов из существующего factory (до той же конечной точки, что и заблокирован). Если вы создали factory для создания каналов, нет причин не закрывать его.
Но почему вы хотите сохранить его открытым? Здесь интересна статья о клиентах WCF, в которой говорится:
Проверка значения System.ServiceModel.ICommunicationObject.State свойство - состояние гонки и не рекомендуется определять, для повторного использования или закрытия канала.
Вместо повторного использования канала вы можете просто создать новый с каналом factory. Подробнее о архитектуре клиента здесь.
Ответ 2
Я нашел главный ответ неточным, поэтому я отвечаю здесь.
Очевидно, что 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
.
Ответ 3
Другой вариант - использовать статический метод CreateChannel:
msdn.microsoft.com/en-us/library/aa344556.aspx