У меня есть приложение WPF, которое использует сервисы WCF для совершения вызовов к серверу.
Я использую это свойство в своем коде для доступа к сервису
private static IProjectWcfService ProjectService
{
get
{
_projectServiceFactory = new ProjectWcfServiceFactory();
return _projectServiceFactory.Create();
}
}
Создавание на фабрике похоже на это
public IProjectWcfService Create()
{
_serviceClient = new ProjectWcfServiceClient();
//ToDo: Need some way of saving username and password
_serviceClient.ClientCredentials.UserName.UserName = "MyUsername";
_serviceClient.ClientCredentials.UserName.Password = "MyPassword";
return _serviceClient;
}
Для доступа к сервисным методам, я использую somethingn как следующее.
ProjectService.Save(dto);
Действительно ли это - хороший подход для того, что я пытаюсь сделать? Я получаю errorthat, я не могу разыскать это, я думаю, может быть связан с наличием слишком многих сервисных открытых соединений клиента (действительно ли это возможно?) замечают, что я никогда не закрываю сервисный клиент или снова использую его.
Что было бы лучшая практика для сервисного клиента WCF быть для вызова WPF?
Заранее спасибо...
Вы на правильном пути, я бы сказал ;-)
В основном, создание клиентского прокси WCF состоит из двух шагов:
Шаг #1 довольно "дорогой" с точки зрения времени и необходимых усилий - так что это определенно хорошая идея сделать это один раз и затем кэшировать экземпляр ProjectWcfServiceFactory
где-нибудь в вашем коде.
Шаг №2 на самом деле довольно легкий, и поскольку канал между клиентом и сервисом может попасть в "поврежденное состояние", когда на сервере происходит исключение (и тогда его нужно создавать заново), кэширование фактического канала как такового менее желательно.
Поэтому общепринятой лучшей практикой будет следующая:
создать ChannelFactory
(в вашем случае: ProjectWcfServiceFactory
) один раз и кэшировать его как можно дольше; сделать эту тяжелую работу только один раз
создать фактический Channel
(здесь: IProjectWcfService
) по мере необходимости, перед каждым вызовом. Таким образом, вам не придется беспокоиться о проверке его состояния и повторном создании по мере необходимости
UPDATE: "А как насчет закрытия канала?" спрашивает Берт ;-) Хорошая мысль!!!
Общепринятая лучшая практика для этого - обернуть вызов сервиса в блок try....catch....finally
. Сложность в том, что при утилизации канала все может пойти не так, и вы можете получить исключение - вот почему обернуть его в блок using(....)
недостаточно.
Итак, в основном у вас есть:
IProjectWcfService client = ChannelFactory.CreateChannel();
try
{
client.MakeYourCall();
}
catch(CommunicationException ce)
{
// do any exception handling of your own
}
finally
{
ICommunicationObject comObj = ((ICommunicationObject)client);
if(comObj.State == CommunicationState.Faulted)
{
comObj.Abort();
}
else
{
comObj.Close();
}
}
И конечно, вы могли бы обернуть это в метод или метод расширения или что-то еще, чтобы не набирать это каждый раз, когда вы делаете вызов службы.
UPDATE:
Книга, которую я всегда рекомендую для быстрого освоения WCF - это Learning WCF Мишеля Леру Бустаманте. Она охватывает все необходимые темы, причем в очень понятной и доступной форме. Она научит вас всему - основам, промежуточным темам, безопасности, управлению транзакциями и так далее - что вам нужно знать, чтобы писать высококачественные, полезные WCF-сервисы.
Более продвинутые темы и более углубленный взгляд на WCF будут рассмотрены в Программирование WCF-сервисов Ювала Лоуи. Он действительно погружается во все технические детали и темы и представляет "библию" для программирования WCF.