让WCF客户端的“调用”成为一种“享受”
推荐WCF客户端实现:享受无止境 - 改进版WCF Client
刚开始使用WCF时,总是在using中进行调用,比如:
using (CnblogsWcfClient client = new CnblogsWcfClient())
{
client.Say("Hello, cnblogs.com!");
}
后来发现,这是微软的一个“骗局”,当时我写了篇博客“不要在using语句中调用WCF服务”。
从此改为这样调用:
CnblogsWcfClient client = new CnblogsWcfClient();
client.Say("Hello, cnblogs.com!");
try
{
client.Close();
}
catch
{
client.Abort();
}
每当写到这样的代码,心理总是有些不舒服。经过近10个月这样的不舒服之后,再也无法忍受。。。
于是,今天决定解决这个问题。。。
从 What is the best workaround for the WCF client `using` block issue? 找到 Practical Functional C# - Part II,发现了解决之道,但其中提供的代码不完整,经过几个小时的摸索,终于找到满意的解决方法。
让WCF客户端的调用成为“享受”的代码如下:
应用程序中调用代码:
调用代码一
//IUserService就是WCF的ServiceContract,是客户端自动生成的代理类
WcfClient.UseService((IUserService userService) => (userService.GetUser(userId)));
调用代码二:
WcfClient.UseService<IUserService , User>(s => s.GetUser(userId));
WcfClient实现代码一(该代码只支持有返回值的WCF服务,推荐第二种实现代码):
public class WcfClient
{
public static TReturn UseService<TChannel, TReturn>(Func<TChannel, TReturn> func)
{
var chanFactory = new ChannelFactory<TChannel>("*");
TChannel channel = chanFactory.CreateChannel();
((IClientChannel)channel).Open();
TReturn result = func(channel);
try
{
((IClientChannel)channel).Close();
}
catch
{
((IClientChannel)channel).Abort();
}
return result;
}
}
解决这个问题的主要时间花在找到上面代码中的那个星号,星号对应的参数名是endpointConfigurationName。
开始时困扰于如何给endpointConfigurationName参数传值。后来,研究了一下自动生成的代理类,也没有与endpointConfigurationName相关的信息,只是继承自System.ServiceModel.ClientBase<T>。然后,通过ILSPy反编译ClientBase<T>的代码,找到了这个星号,见下图:
小结
也许还有更“享受”的调用WCF客户端方法,但是我觉得至少比以前的方法用起来更舒服。解决问题之后,最好的庆祝方式就是写一篇博客。分享的不仅仅是解决方法,还有解决问题之后的那种兴奋!
补充
还有一种WcfClient实现方法(即支持有返回值的WCF服务,也支持无返回值的WCF服务),代码如下:
public static void UseService<TChannel>(Action<TChannel> action)
{
var chanFactory = new ChannelFactory<TChannel>("*");
TChannel channel = chanFactory.CreateChannel();
((IClientChannel)channel).Open();
action(channel);
try
{
((IClientChannel)channel).Close();
}
catch
{
((IClientChannel)channel).Abort();
}
}
WCF客户端调用示例代码:
WcfClient.UseService<IFeedService>(s => s.BeginCreate(feed, null, null));
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· .NET Core 托管堆内存泄露/CPU异常的常见思路
· PostgreSQL 和 SQL Server 在统计信息维护中的关键差异
· DeepSeek “源神”启动!「GitHub 热点速览」
· 我与微信审核的“相爱相杀”看个人小程序副业
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· C# 集成 DeepSeek 模型实现 AI 私有化(本地部署与 API 调用教程)
· spring官宣接入deepseek,真的太香了~
2006-11-02 [调查]是否需要在园子里统一组织开源项目的开发
2005-11-02 所阅读的ASP.NET 2.0文章
2004-11-02 [博客园公告]登录时增加了验证码验证功能