??????? 问题:笔者在项目中需要循环一个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]?
- public?string?GetData(int?id)?
- {?
- string?rstr?=?string.Empty;?
- rstr?=?id.ToString()?+?"---word";?
- return?rstr;?
- }?
??????? 下面我们编写一个实体类,来绑定ListBox控件。源码如下:
- ///?<summary>?
- ///?信息类?属性Id为ID值,属性Infostr为信息类的字符值?
- ///?</summary>?
- public?class?info?
- {?
- int?id;?
- string?infostr;?
- ?
- public?int?Id?
- {?
- get?{?return?id;?}?
- set?{?id?=?value;?}?
- }?
- ?
- public?string?Infostr?
- {?
- get?{?return?infostr;?}?
- set?{?infostr?=?value;?}?
- }?
- }?
??????? 下面我们在XAML文件中添加两个ListBox和两个Button控件。分别用来显示错误的多条数据的情况和正确的N条数据的情况。
?
- <ListBox?Height="193"?HorizontalAlignment="Left"?Margin="61,29,0"?Name="listBox1"?VerticalAlignment="Top"?Width="154"?/>?
- <Button?Content="获取25个WebService数据"?Height="23"?HorizontalAlignment="Left"?Margin="61,240,0"?Name="button1"?VerticalAlignment="Top"?Width="154"?Click="button1_Click"?/>?
- <ListBox?Height="193"?HorizontalAlignment="Left"?Margin="264,0"?Name="listBox2"?VerticalAlignment="Top"?Width="154"?/>?
- <Button?Content="获取5个WebService数据"?Height="23"?HorizontalAlignment="Left"?Margin="264,0"?Name="button2"?VerticalAlignment="Top"?Width="154"?Click="button2_Click"?/>?
??????? 下面我们查看CS中的关键代码如下:
?
- #region?获取到错误的数据条数?条数是N*N?
- ///?<summary>?
- ///?获取错误的多条数据的方法?
- ///?</summary>?
- public?void?GetMoreList()?
- {?
- //清除infoMoreList数据集,然后循环访问WebService方法?
- infoMoreList.Clear();?
- for?(int?i?=?1;?i?<?6;?i++)?
- {?
- MoreClient.GetDataAsync(i);?
- MoreClient.GetDataCompleted?+=?new?EventHandler<GetDataCompletedEventArgs>(wClient_GetDataCompleted);?
- }?
- }?
- void?wClient_GetDataCompleted(object?sender,?GetDataCompletedEventArgs?e)?
- {?
- info?inf?=?new?info()?
- {?
- Id=1,?Infostr=e.Result?
- };?
- infoMoreList.Add(inf);?
- }?
- #endregion?
- ?
- #region?获取正确的数据条数?
- ///?<summary>?
- ///?获取正确数据的方法?
- ///?</summary>?
- public?void?GetList()?
- {?
- //清除infoList数据集,然后循环访问WebService方法?
- infoList.Clear();?
- for?(int?i?=?1;?i?<?6;?i++)?
- {?
- LessClient.GetDataAsync(i);?
- }?
- LessClient.GetDataCompleted?+=?new?EventHandler<GetDataCompletedEventArgs>(wClient_LessGetDataCompleted);?
- }?
- ?
- void?wClient_LessGetDataCompleted(object?sender,?GetDataCompletedEventArgs?e)?
- {?
- info?inf?=?new?info()?
- {?
- 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源代码
- using?System;?
- using?System.Collections.Generic;?
- using?System.Linq;?
- using?System.Web;?
- using?System.Web.Services;?
- ?
- namespace?SLWebService.Web?
- {?
- ///?<summary>?
- ///?Wservice?的摘要说明?
- ///?</summary>?
- [WebService(Namespace?=?"http://tempuri.org/")]?
- [WebServiceBinding(ConformsTo?=?WsiProfiles.BasicProfile1_1)]?
- [System.ComponentModel.ToolboxItem(false)]?
- //?若要允许使用?ASP.NET?AJAX?从脚本中调用此?Web?服务,请取消对下行的注释。?
- //?[System.Web.Script.Services.ScriptService]?
- public?class?Wservice?:?System.Web.Services.WebService?
- {?
- ?
- [WebMethod]?
- public?string?GetData(int?id)?
- {?
- string?rstr?=?string.Empty;?
- rstr?=?id.ToString()?+?"---word";?
- return?rstr;?
- }?
- }?
- }?
MainPage.xaml源代码
- <UserControl?xmlns: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">?
- ?
- <Grid?x:Name="LayoutRoot"?Background="White">?
- <ListBox?Height="193"?HorizontalAlignment="Left"?Margin="61,0"?Name="listBox1"?VerticalAlignment="Top"?Width="154"?/>?
- <Button?Content="获取25个WebService数据"?Height="23"?HorizontalAlignment="Left"?Margin="61,0"?Name="button1"?VerticalAlignment="Top"?Width="154"?Click="button1_Click"?/>?
- <ListBox?Height="193"?HorizontalAlignment="Left"?Margin="264,0"?Name="listBox2"?VerticalAlignment="Top"?Width="154"?/>?
- <Button?Content="获取5个WebService数据"?Height="23"?HorizontalAlignment="Left"?Margin="264,0"?Name="button2"?VerticalAlignment="Top"?Width="154"?Click="button2_Click"?/>?
- </Grid>?
- </UserControl>?
MainPage.xaml.cs源代码
?
- using?System;?
- using?System.Collections.Generic;?
- using?System.Linq;?
- using?System.Net;?
- using?System.Windows;?
- using?System.Windows.Controls;?
- using?System.Windows.Documents;?
- using?System.Windows.Input;?
- using?System.Windows.Media;?
- using?System.Windows.Media.Animation;?
- using?System.Windows.Shapes;?
- using?System.Threading;?
- using?SLWebService.ServiceReference1;?
- namespace?SLWebService?
- {?
- public?partial?class?MainPage?:?UserControl?
- {?
- public?MainPage()?
- {?
- InitializeComponent();?
- //初始化的时候就执行?
- GetMoreList();?
- GetList();?
- }?
- List<info>?infoMoreList?=?new?List<info>();?
- List<info>?infoList?=?new?List<info>();?
- WserviceSoapClient?MoreClient?=?new?WserviceSoapClient();?
- WserviceSoapClient?LessClient?=?new?WserviceSoapClient();?
- private?void?button1_Click(object?sender,?RoutedEventArgs?e)?
- {?
- this.listBox1.ItemsSource?=?infoMoreList;?
- this.listBox1.DisplayMemberPath?=?"Infostr";?
- ?
- }?
- private?void?button2_Click(object?sender,?RoutedEventArgs?e)?
- {?
- this.listBox2.ItemsSource?=?infoList;?
- this.listBox2.DisplayMemberPath?=?"Infostr";?
- ?
- }?
- #region?获取到错误的数据条数?条数是N*N?
- ///?<summary>?
- ///?获取错误的多条数据的方法?
- ///?</summary>?
- public?void?GetMoreList()?
- {?
- //清除infoMoreList数据集,然后循环访问WebService方法?
- infoMoreList.Clear();?
- //错误的循环获取WebBSer?
- for?(int?i?=?1;?i?<?6;?i++)?
- {?
- MoreClient.GetDataAsync(i);?
- MoreClient.GetDataCompleted?+=?new?EventHandler<GetDataCompletedEventArgs>(wClient_GetDataCompleted);?
- }?
- }?
- void?wClient_GetDataCompleted(object?sender,?Infostr=e.Result?
- };?
- infoMoreList.Add(inf);?
- }?
- #endregion?
- ?
- #region?获取正确的数据条数?
- ///?<summary>?
- ///?获取正确数据的方法?
- ///?</summary>?
- public?void?GetList()?
- {?
- //清除infoList数据集,然后循环访问WebService方法?
- infoList.Clear();?
- for?(int?i?=?1;?i?<?6;?i++)?
- {?
- LessClient.GetDataAsync(i);?
- }?
- LessClient.GetDataCompleted?+=?new?EventHandler<GetDataCompletedEventArgs>(wClient_LessGetDataCompleted);?
- }?
- ?
- void?wClient_LessGetDataCompleted(object?sender,?Infostr=e.Result?
- };?
- infoList.Add(inf);?
- }?
- #endregion?
- ?
- }?
- ///?<summary>?
- ///?信息类?属性Id为ID值,属性Infostr为信息类的字符值?
- ///?</summary>?
- public?class?info?
- {?
- int?id;?
- string?infostr;?
- ?
- public?int?Id?
- {?
- get?{?return?id;?}?
- set?{?id?=?value;?}?
- }?
- ?
- public?string?Infostr?
- {?
- get?{?return?infostr;?}?
- set?{?infostr?=?value;?}?
- }?
- }?
- }?
???????? 本实例采用VS2010+Silverlight 4.0编写,点击?SLWebService.rar 下载源代码。