21.循环访问WebService方法来看Silverlight下WebService异步请求

2016-08-20 11:10:45来源:http://chengxingliang.blog.51cto.com/3972944/821967作者:程兴亮人点击



问题:笔者在项目中需要循环一个WebService方法N次,以获得N个结果数据,但是这过程中出现了一些问题,获取到的结果数据量大于笔者的预期且值为N*N。


Silverlight中常见的数据访问方式都是通过类似于WebService异步请求方式来获取的,相信大部分人都会这个WebService的请求 方法,但是在某一个需要输入参数获取一个结果的WebService方法中,假设我们需要循环输入N个参数,然后获取N个结果集的情况下进行的操作会出现 什么情况呢?本文将围绕循环WebService循环访问探讨一下Silverlight中的异步WebService数据请求过程。


首先新建一个Silverlight应用程序项目,在Web项目中添加Wservice.asmx的服务页面,在页面内我们创建一个WebService 方法源码如下,输入参数为1、2、3、4、5的情况下,获得相应的结果为(参数---word)如1---word,2---word。


[WebMethod]publicstringGetData(intid){stringrstr=string.Empty;rstr=id.ToString()+"---word";returnrstr;}

下面我们编写一个实体类,来绑定ListBox控件。源码如下:


///<summary>///信息类属性Id为ID值,属性Infostr为信息类的字符值///</summary>publicclassinfo{intid;stringinfostr;publicintId{get{returnid;}set{id=value;}}publicstringInfostr{get{returninfostr;}set{infostr=value;}}}

下面我们在XAML文件中添加两个ListBox和两个Button控件。分别用来显示错误的多条数据的情况和正确的N条数据的情况。



<ListBoxHeight="193"HorizontalAlignment="Left"Margin="61,29,0,0"Name="listBox1"VerticalAlignment="Top"Width="154"/><ButtonContent="获取25个WebService数据"Height="23"HorizontalAlignment="Left"Margin="61,240,0,0"Name="button1"VerticalAlignment="Top"Width="154"Click="button1_Click"/><ListBoxHeight="193"HorizontalAlignment="Left"Margin="264,29,0,0"Name="listBox2"VerticalAlignment="Top"Width="154"/><ButtonContent="获取5个WebService数据"Height="23"HorizontalAlignment="Left"Margin="264,240,0,0"Name="button2"VerticalAlignment="Top"Width="154"Click="button2_Click"/>

下面我们查看CS中的关键代码如下:



#region获取到错误的数据条数条数是N*N///<summary>///获取错误的多条数据的方法///</summary>publicvoidGetMoreList(){//清除infoMoreList数据集,然后循环访问WebService方法infoMoreList.Clear();for(inti=1;i<6;i++){MoreClient.GetDataAsync(i);MoreClient.GetDataCompleted+=newEventHandler<GetDataCompletedEventArgs>(wClient_GetDataCompleted);}}voidwClient_GetDataCompleted(objectsender,GetDataCompletedEventArgse){infoinf=newinfo(){Id=1,Infostr=e.Result};infoMoreList.Add(inf);}#endregion#region获取正确的数据条数///<summary>///获取正确数据的方法///</summary>publicvoidGetList(){//清除infoList数据集,然后循环访问WebService方法infoList.Clear();for(inti=1;i<6;i++){LessClient.GetDataAsync(i);}LessClient.GetDataCompleted+=newEventHandler<GetDataCompletedEventArgs>(wClient_LessGetDataCompleted);}voidwClient_LessGetDataCompleted(objectsender,GetDataCompletedEventArgse){infoinf=newinfo(){Id=1,Infostr=e.Result};infoList.Add(inf);}#endregion

关键在于for循环之中有没有包括MoreClient.GetDataCompleted事件的加载。


第一种错误的情况下每次循环发出异步请求加载一次GetDataCompleted事件,一共循环五次,那么加载了5次GetDataCompleted事件的时候,也发出了5次的Ansyc(i)请求,所以5*5=25次获取事件结果数据,这是错误的!


第二种正确的情况下每次循环发出异步的Ansyc(i)请求即可,只是在循环完之后加载一次GetDataCompleted事件即可,然后就会执行 5*1=5次获取事件结果处理。通过每刷新程序,然后按Button键得到的右边ListBox数据排列不同可以看出:发出请求的时间顺序和得到结果的时 间顺序是不一致的。


下图展示两种情况得到的数据如下:



本实例的所有源代码如下,点击代码展开观看:


Wservice.asmx.cs源代码
usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Web;usingSystem.Web.Services;namespaceSLWebService.Web{///<summary>///Wservice的摘要说明///</summary>[WebService(Namespace="http://tempuri.org/")][WebServiceBinding(ConformsTo=WsiProfiles.BasicProfile1_1)][System.ComponentModel.ToolboxItem(false)]//若要允许使用ASP.NETAJAX从脚本中调用此Web服务,请取消对下行的注释。//[System.Web.Script.Services.ScriptService]publicclassWservice:System.Web.Services.WebService{[WebMethod]publicstringGetData(intid){stringrstr=string.Empty;rstr=id.ToString()+"---word";returnrstr;}}}
MainPage.xaml源代码




<UserControlxmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk"x:Class="SLWebService.MainPage"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d="http://schemas.microsoft.com/expression/blend/2008"xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"mc:Ignorable="d"d:DesignHeight="800"d:DesignWidth="800"><Gridx:Name="LayoutRoot"Background="White"><ListBoxHeight="193"HorizontalAlignment="Left"Margin="61,29,0,0"Name="listBox1"VerticalAlignment="Top"Width="154"/><ButtonContent="获取25个WebService数据"Height="23"HorizontalAlignment="Left"Margin="61,240,0,0"Name="button1"VerticalAlignment="Top"Width="154"Click="button1_Click"/><ListBoxHeight="193"HorizontalAlignment="Left"Margin="264,29,0,0"Name="listBox2"VerticalAlignment="Top"Width="154"/><ButtonContent="获取5个WebService数据"Height="23"HorizontalAlignment="Left"Margin="264,240,0,0"Name="button2"VerticalAlignment="Top"Width="154"Click="button2_Click"/></Grid></UserControl>


MainPage.xaml.cs源代码

usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Net;usingSystem.Windows;usingSystem.Windows.Controls;usingSystem.Windows.Documents;usingSystem.Windows.Input;usingSystem.Windows.Media;usingSystem.Windows.Media.Animation;usingSystem.Windows.Shapes;usingSystem.Threading;usingSLWebService.ServiceReference1;namespaceSLWebService{publicpartialclassMainPage:UserControl{publicMainPage(){InitializeComponent();//初始化的时候就执行GetMoreList();GetList();}List<info>infoMoreList=newList<info>();List<info>infoList=newList<info>();WserviceSoapClientMoreClient=newWserviceSoapClient();WserviceSoapClientLessClient=newWserviceSoapClient();privatevoidbutton1_Click(objectsender,RoutedEventArgse){this.listBox1.ItemsSource=infoMoreList;this.listBox1.DisplayMemberPath="Infostr";}privatevoidbutton2_Click(objectsender,RoutedEventArgse){this.listBox2.ItemsSource=infoList;this.listBox2.DisplayMemberPath="Infostr";}#region获取到错误的数据条数条数是N*N///<summary>///获取错误的多条数据的方法///</summary>publicvoidGetMoreList(){//清除infoMoreList数据集,然后循环访问WebService方法infoMoreList.Clear();//错误的循环获取WebBSerfor(inti=1;i<6;i++){MoreClient.GetDataAsync(i);MoreClient.GetDataCompleted+=newEventHandler<GetDataCompletedEventArgs>(wClient_GetDataCompleted);}}voidwClient_GetDataCompleted(objectsender,GetDataCompletedEventArgse){infoinf=newinfo(){Id=1,Infostr=e.Result};infoMoreList.Add(inf);}#endregion#region获取正确的数据条数///<summary>///获取正确数据的方法///</summary>publicvoidGetList(){//清除infoList数据集,然后循环访问WebService方法infoList.Clear();for(inti=1;i<6;i++){LessClient.GetDataAsync(i);}LessClient.GetDataCompleted+=newEventHandler<GetDataCompletedEventArgs>(wClient_LessGetDataCompleted);}voidwClient_LessGetDataCompleted(objectsender,GetDataCompletedEventArgse){infoinf=newinfo(){Id=1,Infostr=e.Result};infoList.Add(inf);}#endregion}///<summary>///信息类属性Id为ID值,属性Infostr为信息类的字符值///</summary>publicclassinfo{intid;stringinfostr;publicintId{get{returnid;}set{id=value;}}publicstringInfostr{get{returninfostr;}set{infostr=value;}}}}

本实例采用VS2010+Silverlight 4.0编写,点击SLWebService.rar 下载源代码。



最新文章

123

最新摄影

微信扫一扫

第七城市微信公众平台