搜索 | 会员  
asp.net 动态webservice 缓存方式提升效率
来源: CIOZJ   作者:新雨  日期:2014-10-13  类别:编程语言  主题:.NET  编辑:新雨
原来做项目的时候使用webservice大部分都是用的静态连接方式获取数据,可是缺点就是部能实施的更新webservice,总是得重新生成才行,如果项目一旦部署webservice再有修改那么静态的引用也得相应

原来做项目的时候使用webservice大部分都是用的静态连接方式获取数据,可是缺点就是部能实施的更新webservice,总是得重新生成才行,如果项目一旦部署webservice再有修改那么静态的引用也得相应的修改和更新,很不爽。

所以就想到了用动态的webservice来实现,不过缺点就是效率低了,响应速度真是让人着急。

网上有很多例子动态webservice的例子如:

    //http://blog.csdn.net/lzy_1515
    public class link_webservice
    {
        public link_webservice()
        {
            //
            //TODO: 在此处添加构造函数逻辑
            //
        }
 
        /// <summary>
        /// 动态调用WebService
        /// </summary>
        /// <param name="url">WebService地址</param>
        /// <param name="methodname">方法名(模块名)</param>
        /// <param name="args">参数列表</param>
        /// <returns>object</returns>
        public static object InvokeWebService(string url, string methodname, object[] args)
        {
            return InvokeWebService(url, null, methodname, args);
        }
//http://blog.csdn.net/lzy_1515
        /// <summary>
        /// 动态调用WebService
        /// </summary>
        /// <param name="url">WebService地址</param>
        /// <param name="classname">类名</param>
        /// <param name="methodname">方法名(模块名)</param>
        /// <param name="args">参数列表</param>
        /// <returns>object</returns>
        public static object InvokeWebService(string url, string classname, string methodname, object[] args)
        {
            string @namespace = "ServiceBase.WebService.DynamicWebLoad";
            if (classname == null || classname == "")
            {
                classname = GetClassName(url);
            }
            //获取服务描述语言(WSDL)
            WebClient wc = new WebClient();
            Stream stream = wc.OpenRead(url + "?WSDL");
            ServiceDescription sd = ServiceDescription.Read(stream);
            ServiceDescriptionImporter sdi = new ServiceDescriptionImporter();
            sdi.AddServiceDescription(sd, "", "");
            CodeNamespace cn = new CodeNamespace(@namespace);
            //生成客户端代理类代码
            CodeCompileUnit ccu = new CodeCompileUnit();
            ccu.Namespaces.Add(cn);
            sdi.Import(cn, ccu);
            CSharpCodeProvider csc = new CSharpCodeProvider();
            ICodeCompiler icc = csc.CreateCompiler();
            //设定编译器的参数
            CompilerParameters cplist = new CompilerParameters();
            cplist.GenerateExecutable = false;
            cplist.GenerateInMemory = true;
            cplist.ReferencedAssemblies.Add("System.dll");
            cplist.ReferencedAssemblies.Add("System.XML.dll");
            cplist.ReferencedAssemblies.Add("System.Web.Services.dll");
            cplist.ReferencedAssemblies.Add("System.Data.dll");
            //编译代理类
 
            CompilerResults cr = icc.CompileAssemblyFromDom(cplist, ccu);
            if (true == cr.Errors.HasErrors)
            {
                System.Text.StringBuilder sb = new StringBuilder();
                foreach (CompilerError ce in cr.Errors)
                {
                    sb.Append(ce.ToString());
                    sb.Append(System.Environment.NewLine);
                }
                throw new Exception(sb.ToString());
            }
 
            //生成代理实例,并调用方法
 
            System.Reflection.Assembly assembly = cr.CompiledAssembly;
            Type t = assembly.GetType(@namespace + "." + classname, true, true);
            object obj = Activator.CreateInstance(t);
            System.Reflection.MethodInfo mi = t.GetMethod(methodname);
            return mi.Invoke(obj, args);
 
        }
 
        private static string GetClassName(string url)
        {
            string[] parts = url.Split('/');
            string[] pps = parts[parts.Length - 1].Split('.');
            return pps[0];
        }

这个例子可以实现动态连接可是效率不是很高,因为每次请求的时候都重新生成,所以慢。

 

后来想了想要是加了缓存会不会提高一些速度,经过改进成功了,第一次的时候他会进行生成,以后在进来

就去缓存里去取了,响应时间0秒。

 

修改后的代码如下:

    // http://blog.csdn.net/lzy_1515 
    //string url = "http://url.asmx";
    //string[] args = new string[2];
    //args[0] = 0;
    //args[1] = "12";
    //object result = DynamicWebServices.InvokeWebService(url, "Getcc", args);
    //this.label_Result.Text = result.ToString();
 
 
    public class DynamicWebServices
    {
        static SortedList<string, Type> _typeList = new SortedList<string, Type>();
 
        #region InvokeWebService
 
        static string GetCacheKey(string url, string className)
        {
            return url.ToLower() + className;
        }
        static Type GetTypeFromCache(string url, string className)
        {
            string key = GetCacheKey(url, className);
            foreach (KeyValuePair<string, Type> pair in _typeList)
            {
                if (key == pair.Key)
                {
                    return pair.Value;
                }
            }
 
            return null;
        }
        static Type GetTypeFromWebService(string url, string className)
        {
            string @namespace = "EnterpriseServerBase.WebService.DynamicWebCalling";
            if ((className == null) || (className == ""))
            {
                className = GetWsClassName(url);
            }
//http://blog.csdn.net/lzy_1515
            //获取WSDL
            WebClient wc = new WebClient();
            Stream stream = wc.OpenRead(url + "?WSDL");
            ServiceDescription sd = ServiceDescription.Read(stream);
            ServiceDescriptionImporter sdi = new ServiceDescriptionImporter();
            sdi.AddServiceDescription(sd, "", "");
            CodeNamespace cn = new CodeNamespace(@namespace);
 
            //生成客户端代理类代码
            CodeCompileUnit ccu = new CodeCompileUnit();
            ccu.Namespaces.Add(cn);
            sdi.Import(cn, ccu);
            CSharpCodeProvider csc = new CSharpCodeProvider();
            ICodeCompiler icc = csc.CreateCompiler();
 
            //设定编译参数
            CompilerParameters cplist = new CompilerParameters();
            cplist.GenerateExecutable = false;
            cplist.GenerateInMemory = true;
            cplist.ReferencedAssemblies.Add("System.dll");
            cplist.ReferencedAssemblies.Add("System.XML.dll");
            cplist.ReferencedAssemblies.Add("System.Web.Services.dll");
            cplist.ReferencedAssemblies.Add("System.Data.dll");
 
            //编译代理类
            CompilerResults cr = icc.CompileAssemblyFromDom(cplist, ccu);
            if (true == cr.Errors.HasErrors)
            {
                System.Text.StringBuilder sb = new System.Text.StringBuilder();
                foreach (System.CodeDom.Compiler.CompilerError ce in cr.Errors)
                {
                    sb.Append(ce.ToString());
                    sb.Append(System.Environment.NewLine);
                }
                throw new Exception(sb.ToString());
            }
 
            //生成代理实例,并调用方法
            System.Reflection.Assembly assembly = cr.CompiledAssembly;
            Type t = assembly.GetType(@namespace + "." + className, true, true);
 
            return t;
        }
 
        //动态调用web服务
        public static object InvokeWebService(string url, string methodName, object[] args)
        {
            return InvokeWebService(url, null, methodName, args);
        }
 
        public static object InvokeWebService(string url, string className, string methodName, object[] args)
        {
            try
            {
                Type t = GetTypeFromCache(url, className);
                if (t == null)
                {
                    t = GetTypeFromWebService(url, className);
 
                    //添加到缓冲中
                    string key = GetCacheKey(url, className);
                    _typeList.Add(key, t);
                }
 
                object obj = Activator.CreateInstance(t);
                MethodInfo mi = t.GetMethod(methodName);
 
                return mi.Invoke(obj, args);
            }
            catch (Exception ex)
            {
                throw new Exception(ex.InnerException.Message, new Exception(ex.InnerException.StackTrace));
            }
        }
 
        private static string GetWsClassName(string wsUrl)
        {
            string[] parts = wsUrl.Split('/');
            string[] pps = parts[parts.Length - 1].Split('.');
 
            return pps[0];
        }
        #endregion
 
 
 

 

德仔网尊重行业规范,每篇文章都注明有明确的作者和来源;德仔网的原创文章,请转载时务必注明文章作者和来源:德仔网;
头条那些事
大家在关注
我们的推荐
也许感兴趣的
干货
了解一下吧