protected void btnCompiler_Click(object sender, EventArgs e) { if (txtPassword.Text == "Tony") { ManualResetEvent mre = new ManualResetEvent(false); for (int i = 0; i < 10; i++) { Thread t = new Thread(() => { mre.WaitOne(); SoapClientItem item = SoapClientCache.GetItem("http://10.30.1.6/CKMService/WebService/ESBEmailService.asmx", "OA_Email"); }); t.Start(); } mre.Set(); } }
/// <summary> /// 获取到指定URL的代理程序集 /// </summary> /// <param name="url"></param> /// <returns></returns> public static SoapClientItem GetItem(String url, String serviceName) { if (!s_soapClientDict.ContainsKey(url)) { lock (GetLock(url)) { if (!s_soapClientDict.ContainsKey(url)) { try { SoapClientItem item = LoadAssembly(url, serviceName); s_soapClientDict.Add(url, item); } catch (Exception ex) { XTrace.WriteException(ex); throw ex; } } } } return(s_soapClientDict[url]); }
/// <summary> /// 加载代理程序集 /// </summary> /// <param name="url"></param> /// <param name="serviceName"></param> /// <returns></returns> private static SoapClientItem LoadAssembly(String url, String serviceName) { String assemblyPath = GetAssemblyPath(url); String portTypeFullName = String.Empty; // 注意此处要用全名:命名空间.类名 // 如果代理程序集不存在则编译生成代理程序集,否则直接加载 if (!File.Exists(assemblyPath)) { portTypeFullName = CompilerAssembly(url, serviceName, assemblyPath); } else { portTypeFullName = AssemblyType.GetInstance(assemblyPath).PortType; } // 如果没有获取到端口类型则清空程序集缓存并抛出异常 if (portTypeFullName == String.Empty) { ClearCache(url); throw new Exception(String.Format("获取服务:{0}『{1}』的端口类型失败!", serviceName, url)); } Assembly asm = null; using (FileStream fs = File.OpenRead(assemblyPath)) { asm = Assembly.Load(fs.ReadBytes(fs.Length)); // 此处采用文件流进行加载,使得加载后的程序集仍然可以被重新编译 } if (asm == null) { throw new Exception(String.Format("加载代理程序集{0}失败!", assemblyPath)); } //Assembly asm = result.CompiledAssembly; //Type portType = asm.GetType(String.Format("{0}.{1}", serviceName, portTypeName)); //Type reqType = asm.GetType(String.Format("{0}.request", serviceName)); // 如果在前面为代理类添加了命名空间,此处需要将命名空间添加到类型前面。 Type portType = GetTypeFromAssembly(asm, portTypeFullName, assemblyPath); Type reqType = GetTypeFromAssembly(asm, String.Format("{0}.request", portTypeFullName.Split('.')[0]), assemblyPath); // 创建端口类对象 Object port = Activator.CreateInstance(portType); if (port == null) { throw new Exception(String.Format("创建:{0}『{1}』的端口类型对象失败!", serviceName, url)); } // 将超时设置为10分钟 portType.InvokeMember("Timeout", BindingFlags.SetProperty, null, port, new Object[] { 10 * 60 * 1000 }); SoapClientItem item = new SoapClientItem() { ProxyAssembly = asm, PortObject = port, PortType = portType, RequestType = reqType }; return(item); }
/// <summary> /// 加载代理程序集 /// </summary> /// <param name="url"></param> /// <param name="serviceName"></param> /// <returns></returns> private static SoapClientItem LoadAssembly(String url, String serviceName) { String assemblyPath = GetAssemblyPath(url); String portTypeFullName = String.Empty; // 注意此处要用全名:命名空间.类名 // 如果代理程序集不存在则编译生成代理程序集,否则直接加载 if (!File.Exists(assemblyPath)) { portTypeFullName = CompilerAssembly(url, serviceName, assemblyPath); } else { portTypeFullName = AssemblyType.GetInstance(assemblyPath).PortType; } // 如果没有获取到端口类型则清空程序集缓存并抛出异常 if (portTypeFullName == String.Empty) { ClearCache(url); throw new Exception(String.Format("获取服务:{0}『{1}』的端口类型失败!", serviceName, url)); } Assembly asm = null; using (FileStream fs = File.OpenRead(assemblyPath)) { asm = Assembly.Load(fs.ReadBytes(fs.Length)); // 此处采用文件流进行加载,使得加载后的程序集仍然可以被重新编译 } if (asm == null) throw new Exception(String.Format("加载代理程序集{0}失败!", assemblyPath)); //Assembly asm = result.CompiledAssembly; //Type portType = asm.GetType(String.Format("{0}.{1}", serviceName, portTypeName)); //Type reqType = asm.GetType(String.Format("{0}.request", serviceName)); // 如果在前面为代理类添加了命名空间,此处需要将命名空间添加到类型前面。 Type portType = GetTypeFromAssembly(asm, portTypeFullName, assemblyPath); Type reqType = GetTypeFromAssembly(asm, String.Format("{0}.request", portTypeFullName.Split('.')[0]), assemblyPath); // 创建端口类对象 Object port = Activator.CreateInstance(portType); if(port == null) throw new Exception(String.Format("创建:{0}『{1}』的端口类型对象失败!", serviceName, url)); // 将超时设置为10分钟 portType.InvokeMember("Timeout", BindingFlags.SetProperty, null, port, new Object[] { 10 * 60 * 1000 }); SoapClientItem item = new SoapClientItem() { ProxyAssembly = asm, PortObject = port, PortType = portType, RequestType = reqType }; return item; }