java第一次调用WebService慢和解决办法

 时间:2026-02-14 10:05:38

1、通常的做法是在程序启动的时候,后台逐一调用一遍所有的WebService,还有人利用多线程来解决这个问题。

2、1.       添加Web引用的时候,WebService在客户端有一个代理,如下:

[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Web.Services", "2.0.50727.42")]    

[System.Diagnostics.DebuggerStepThroughAttribute()]    

[System.ComponentModel.DesignerCategoryAttribute("code")]    

[System.Web.Services.WebServiceBindingAttribute(Name="WebService1Soap", Namespace="http://tempuri.org/")   

public partial class WebService1 : 

System.Web.Services.Protocols.SoapHttpClientProtocol

客户端调用WebServivce就是通过这个代理类来调用的。

3、2.       调用WebService方法,客户端和服务器端通信是Xml,所以代理类跟Xml之间就有序列化和反序列化的过程

4、3.       客户端调用WebService的过程如下:

a)         客户端调用代理类Hello world方法

string str = (new Service2.WebService1()).HelloWorld ();

b)         代理类调用基类SoapHttpClientProtocal的Invoke方法:

  [System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://tempuri.org/HelloWorld0766", RequestNamespace="http://tempuri.org/", ResponseNamespace="http://tempuri.org/", Use=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)]

        public string HelloWorld() {

            object[] results = this.Invoke("HelloWorld", new object[0]);

            return ((string)(results[0]));

        }

c)         SoapHttpClientProtocal进行Soap序列化Soap头和方法,都是这个类自己做的,但是输入参数和返回值,是利用的XmlSerializer,输入参数要序列化,返回值要反序列化。

 protected object[] Invoke(string methodName, object[] parameters)

        {

                …

                try

                {

                    message1.SetStream(stream1);

                    this.Serialize(message1);//注1

                }

               …

                response1 = this.GetWebResponse(request1);

                Stream stream2 = null;

                try

                {

                    stream2 = response1.GetResponseStream();

                    objArray1 = this.ReadResponse(message1, response1, stream2, false);//注2

                }

          }

         

注1:this.Serialize中有一句参数序列化的代码如下

          method1.parameterSerializer.Serialize(writer1, message.GetParameterValues(), null, flag1 ? text2 : null);

注2:this.ReadResponse中有一句返回值的反序列化的代码如下

          message.SetParameterValues((object[]) method1.returnSerializer.Deserialize(reader1, flag1 ? text1 : null));

d)         XmlSerializer会缓存临时程序集,这个程序集作用是序列化和反序列化,如果缓存中没有会调用TempAssembly产生一个

Static的缓存(就是我们每次调用慢的罪魁祸首):private static TempAssemblyCache cache;

获取缓存中的程序集:this.tempAssembly = XmlSerializer.cache[defaultNamespace, type];

缓存中没有就去加载:Assembly assembly1 = TempAssembly.LoadGeneratedAssembly(type, defaultNamespace, outimplementation1);

加载没有就去产生(会生成临时文件并编译,很慢):

this.tempAssembly = new TempAssembly(new XmlMapping[] { this.mapping }, assembly1, implementation1);

e)         TempAssemlby这个类负责加载以及产生临时程序集

在LoadGeneratedAssemlby方法中,有一段逻辑,就是默认去加载序列化类,这个类的命名是规则如下

        internal static string GetTempAssemblyName(AssemblyName parent, string ns)

        {

            return (parent.Name + ".XmlSerializers" + (((ns == null) || (ns.Length == 0)) ? "" : ("." + ns.GetHashCode())));

        }

       同时,如果加载失败会触发AppDomain.CurrentDomain.AssemblyResolve事件

5、4.       结论

1)   WebService的序列化是调用XmlSerializer

2)   WebService慢,是因为产生序列化类慢,所谓的临时文件都是XmlSerializer的中间代码。可以在config文件中加入如下的配置,临时序列化的文件就不会被删除了,WinForm程序是*.exe.config,asp.net是web.config。

<configuration>  <system.diagnostics>    <switches>      <add name="XmlSerialization.Compilation" value="4"/>    </switches>  </system.diagnostics></configuration>

  • 球球大作战怎么合作?
  • 如何制作电子管胆机音箱
  • 陶瓷纤维板如何防水
  • 小儿感冒 发烧 咳嗽 用艾灸
  • 武当山乌鸦岭旅游好玩吗
  • 热门搜索
    婚纱图片大全大图 工作自我鉴定怎么写 图片库大全 高考怎么填志愿 沈阳大学怎么样 微信账号怎么改 观致3怎么样 幼儿讲故事视频大全 内存卡读不出来怎么办 帝国时代2秘籍大全