• 微软原版系统

  • 一键重装系统

  • 纯净系统

  • 在线技术客服

魔法猪系统重装大师 一键在线制作启动 U 盘 PE 系统 用一键重装的魔法拯救失去灵魂的系统
当前位置:首页 > 教程 > 电脑教程

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

时间:2015年04月02日 15:36:02    来源:魔法猪系统重装大师官网    人气:13125

刚学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
{
    /// 


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

        private static TResult TryFunc(Func 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();
                    _ChannelDic.Add(tChannelName, instance);
                }
            }
            else
            {
                instance = _ChannelDic[tChannelName];
            }
            if (instance.State != CommunicationState.Opened && instance.State != CommunicationState.Opening)
                instance.Open();
            return instance;
        }

        /// 
        /// 直接调用,无返回值
        /// 

        public static void Invoke(Action action)
        {
            TChannel instance = GetChannel();
            TryFunc(
                client =>
                {
                    action(client);
                    return (object)null;
                }
                , instance);
        }
        /// 
        /// 有返回值的调用
        /// 

        public static TResult Invoke(Func func)
        {
            TChannel instance = GetChannel();
            ICommunicationObject channel = instance as ICommunicationObject;
            TResult returnValue = default(TResult);
            returnValue = TryFunc(func, instance);
            return returnValue;
        }
      }
}

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

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

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

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

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

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

   {

    int tmpCount = -1;

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

    count = tmpCount;

  }
}

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

WCF,编程,中,需要,及时,关闭,的,案例,分享,
栏目:电脑教程 阅读:1000 2023/12/27
Win7教程 更多>>
U盘教程 更多>>
Win10教程 更多>>
魔法猪学院 更多>>

Copyright © 2015-2023 魔法猪 魔法猪系统重装大师

本站发布的系统仅为个人学习测试使用,请在下载后24小时内删除,不得用于任何商业用途,否则后果自负,请支持购买微软正版软件。

在线客服 查看微信 返回顶部