我有一个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;
}
要访问服务方法,我使用以下内容。
ProjectService.Save(dto);
这是我尝试做的好方法吗?我得到了一个我无法追踪的错误,我认为可能会打开过多的服务客户端连接(这可能吗?)注意我从不关闭服务客户端或重复使用它。
WCF服务客户端的最佳做法是什么才能用于WPF呼叫?
提前致谢...
答案 0 :(得分:12)
你说的是正确的,我会说; - )
基本上,创建WCF客户端代理的过程分为两步:
步骤#1在所需的时间和精力方面非常“昂贵” - 所以一次这样做绝对是个好主意,然后在代码中的某处缓存ProjectWcfServiceFactory
的实例。
步骤#2实际上非常轻量级,并且因为当服务器上发生异常(然后需要从头开始重新创建)时,客户端和服务之间的通道可能会陷入“故障状态”,因此缓存实际的频道本身不太理想。
因此,普遍接受的最佳做法是:
创建ChannelFactory<T>
(在您的情况下:ProjectWcfServiceFactory
)一次并尽可能长时间地缓存它;只做一次重举
在每次通话之前根据需要创建实际Channel
(此处为:IProjectWcfService
)。这样,您不必担心检查其状态并根据需要重新创建它
更新:“关闭频道怎么样?”问Burt ;-)好点!!
为此,最佳做法是将您的服务电话包裹在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();
}
}
当然,你可以很好地将它包装成方法或扩展方法或其他东西,以便每次拨打服务电话时都不必输入。
更新:
Michele Leroux Bustamante撰写的Learning WCF是我一直建议在WCF中快速启动和运行的书。她涵盖了所有必要的主题,并且以一种非常容易理解和平易近人的方式。这将教会您编写高质量,有用的WCF服务所需的一切 - 基础知识,中间主题,安全性,事务控制等等。
Juval Lowy将Programming WCF Services涵盖更高级的主题以及对WCF的更深入了解。他真正深入研究了所有技术细节和主题,并为WCF编程提供了“圣经”。