您的位置:首页 > 编程语言 > ASP

asp.net 动态webservice 缓存方式提升效率

2011-04-16 12:31 155 查看
原来做项目的时候使用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];
}
//http://blog.csdn.net/lzy_1515


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

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

就去缓存里去取了,响应时间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

// http://blog.csdn.net/lzy_1515


个人的想法就是这样,如果有更好的方法请多多交流。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: