西西软件园多重安全检测下载网站、值得信赖的软件下载站!
软件
软件
文章
搜索

首页编程开发其它知识 → WCF编程中需要及时关闭的案例分享

WCF编程中需要及时关闭的案例分享

相关软件相关文章发表评论 来源:西西整理时间:2011/4/24 7:57:26字体大小:A-A+

作者:西西点击:138次评论:2次标签: WCF

手机QQ2017 for Androidv6.6.9 官方最新版
  • 类型:社交聊天大小:37.8M语言:中文 评分:8.0
  • 标签:
立即下载

刚学WCF的时候没发现这个问题,调得很愉快却没有发现其实“暗藏杀机”,可谓危险重重,还好后来觉得是有些不妥,于是google“WCF需要关闭吗”,立马找到了几个博客园的链接,进去一看,各位大侠均纷纷表示“关是一定要关的,但是你还不能用完就关,因为关了,就不能再打开了,还得New,可以New的成本又有一点高”,好吧,这么说来就只有好好规划一下了。

  那么什么时候该关呢,答案是异常了的时候,MSDN给出了代码(错误处理部分,找不到链接了,见谅)

 

      catch (CommunicationException)
            {
                client.Abort();
            }
            catch (TimeoutException)
            {
                clent.Abort();
            }

 所以这样一来,就有了解决方案,那就是在每一处需要调用Wcf和代码里加上try catch,大概就成了如下这样

UserClient client = new UserClient();
try
{
client.Create(new User(){
     UserName="xian",
     Password="123"});
}

catch (CommunicationException)
{
   client.Abort();
}
catch (TimeoutException)
{
   clent.Abort();
}

   这样挺好的,没错,不过我们总不可能只调用一个Wcf接口吧,我们要调的可是一系列,也就是若干接口,那么就我们就需要写很多重复的错误处理代码块了。这样原来没什么问题,而且是理所当然的事情。可是我记得某位老鸟说过当代码出现很大程度重复的时候你就该重构它了(也是在博客园看到了,很普通但深入人心的道理),并且为了让代码好看一点,我们还是想想好点的办法。

如果你有些经验,肯定马上就去想到使用委托来实现消除代码的冗余,是的,下面就是我这次的实现方式,代码如下: 

ServiceInvokeHelper调用辅助类

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;

namespace Helper
{
    /// <summary>
    /// Wcf服务调用辅助类
    /// </summary
    public static class ServiceInvokeHelper<TChannel> where TChannel : ICommunicationObject, new()
    {
        #region private fields
        private static Dictionary<string, TChannel> _ChannelDic = new Dictionary<string, TChannel>();
        private static object _Lockhelper = new object();

        private static TResult TryFunc<TResult>(Func<TChannel, TResult> func, TChannel channel)
        {
            string tChannelName = typeof(TChannel).FullName;
            try
            {
                return func(channel);
            }
            catch (CommunicationException)
            {
                channel.Abort();
                lock (_Lockhelper)
                    _ChannelDic.Remove(tChannelName);
                throw;
            }
            catch (TimeoutException)
            {
                channel.Abort();
                lock (_Lockhelper)
                    _ChannelDic.Remove(tChannelName);
                throw;
            }
            catch (Exception)
            {
                channel.Abort();
                lock (_Lockhelper)
                    _ChannelDic.Remove(tChannelName);
                throw;
            }
      }

        private static TChannel GetChannel()
        {
            TChannel instance;
            string tChannelName = typeof(TChannel).FullName;
            if (!_ChannelDic.ContainsKey(tChannelName))
            {
                lock (_Lockhelper)
                {
                    instance = Activator.CreateInstance<TChannel>();
                    _ChannelDic.Add(tChannelName, instance);
                }
            }
            else
            {
                instance = _ChannelDic[tChannelName];
            }
            if (instance.State != CommunicationState.Opened && instance.State != CommunicationState.Opening)
                instance.Open();
            return instance;
        }

        /// <summary>
        /// 直接调用,无返回值
        /// </summary>
        public static void Invoke(Action<TChannel> action)
        {
            TChannel instance = GetChannel();
            TryFunc(
                client =>
                {
                    action(client);
                    return (object)null;
                }
                , instance);
        }
        /// <summary>
        /// 有返回值的调用
        /// </summary>
        public static TResult Invoke<TResult>(Func<TChannel, TResult> func)
        {
            TChannel instance = GetChannel();
            ICommunicationObject channel = instance as ICommunicationObject;
            TResult returnValue = default(TResult);
            returnValue = TryFunc(func, instance);
            return returnValue;
        }
      }
}

  有了以上代码,我们就可以这样调Wcf了

ServiceInvokeHelper<UserClient>.Invoke(client=>client.Create({new User{
    UserName="xian";
    Password="123";
}}));

  测试过程中发现这样不支持out 和ref参数的调用,比如这样是不可以的

public void GetUserList(int pageindex,int pagesize,ref count)
{
     return ServiceInvokeHelper<UserClient>.Invoke(client=>client.GetUserList(pageindex,pagesize,ref count));
}

  但是我们可以变通成如下模样

public void GetUserList(int pageindex,int pagesize,ref count)
{
    return ServiceInvokeHelper<UserClient>.Invoke(client=>

   {

    int tmpCount = -1;

    client.GetUserList(pageindex,pagesize,ref tmpCount));

    count = tmpCount;

  }
}

  是不是方便许多,并且也不但心因为关闭不及时造成连接数到达上限的情况,看起来不起眼的一个东西就分享到这时,感谢你的阅读!

    寂寞交友
    (73)寂寞交友
    寂寞交友由西西为大家整理一系列火热的社交应用,因为寂寞而交友,随着时代的发展,人们越来越无法满足现有的交际圈子,对于择偶标准的提高,催生出一系列单身男女的情感问题,压抑的情绪需要得到一定的释放,如果你想找寻属于自己的缘分,就赶快下载吧。交友软件排行微信企鹅之子的基数之巨大,寂寞的时候摇一摇,丝男也会有春天不过企鹅之子也有个弊病,依托于的用户资源,环肥燕瘦难以保证。来往来往是拼爹的,背靠大树好乘凉。...更多>>
    生活分享
    (13)生活分享
    生活分享系列是由西西为大家整理,当前的各类软件都是服务于我们的生活,只是着重点不同,有聊天有美食有娱乐有旅行,西西特地为大家准备了一些日常生活中常用的小工具,相信能在平时的日常生活中用到,让我们能更好的品味生活。生活小妙招巧用牙膏若有小面积皮肤损伤或烧伤烫伤,抹上少许牙膏,可立即止血止痛,也可防止感染,疗效颇佳。巧除纱窗油腻可将洗衣粉吸烟剩下的烟头一起放在水里,待溶解后,拿来擦玻璃窗纱窗,效果均不...更多>>
    2015最受欢迎APP
    (27)2015最受欢迎APP
    中国最受欢迎榜单发布,西西第一时间为用户推出最受欢迎排行榜专区下载,在这里你可以下载到中国最受欢迎的,在整个市场,实际上仍旧是占领主导地位。中国最受欢迎榜单前分别是微信手机淘宝搜狗输入法浏览器支付宝钱包浏览器爱奇艺今日头条百度地图酷狗音乐大众点评滴滴出行等等。整个市场可以分成三大类第一类是移动社交移动出行手机地图移动购物等领域已经是大局已定。微信移动社交,以及快的滴滴手机地图手机淘宝移动商城等领域...更多>>
    00后最常用的app
    (29)00后最常用的app
    西西软件园为用户带来后手机必备软件大全,最常用的手机下载,一次性搞定这些热门的社交软件和游戏,让你的生活更加精彩,下面看下部分软件介绍社交软件手机,手机移动版提供多媒体沟通服务,方便用户在移动设备上通过语音图片视频等方式轻松交流。致力于更完美的移动社交娱乐与生活体验乐在沟通年,聊天欢乐亿人微信,微信,数亿人使用,能通过手机网络给好友发送语音文字消息表情图片和视频,还可分享照片到朋友圈。通过摇一摇查...更多>>
    qq2016
    (11)qq2016
    每年年初腾讯都会发布当年最新版的,正是腾讯官方发布的正式版。虽然从版开始就不再以年号明明而是以版本,不过用户还是习惯的年号版本。最新版的因为刚刚发布肯定是有一些细节上的问题的,不过大家可以体验到新版的功能特性也是很不错的,如果你喜欢折腾可以来西西下载版,这里西西给大家提供了最新的电脑版下载及手机版下载。...更多>>

    相关评论

    阅读本文后您有什么感想? 已有人给出评价!

    • 8 喜欢喜欢
    • 3 顶
    • 1 难过难过
    • 5 囧
    • 3 围观围观
    • 2 无聊无聊

    热门评论

    最新评论

    发表评论 查看所有评论(2)

    昵称:
    表情: 高兴 可 汗 我不要 害羞 好 下下下 送花 屎 亲亲
    字数: 0/500 (您的评论需要经过审核才能显示)