问题:笔者在项目中需要循环一个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,0" Name="listBox1" VerticalAlignment="Top" Width="154" />
- <Button Content="获取25个WebService数据" Height="23" HorizontalAlignment="Left" Margin="61,240,0,0" Name="button1" VerticalAlignment="Top" Width="154" Click="button1_Click" />
- <ListBox Height="193" HorizontalAlignment="Left" Margin="264,29,0,0" Name="listBox2" VerticalAlignment="Top" Width="154" />
- <Button Content="获取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>
- 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数据排列不同可以看出:发出请求的时间顺序和得到结果的时 间顺序是不一致的。
下图展示两种情况得到的数据如下:
本实例的所有源代码如下,点击代码展开观看:
- 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;
- }
- }
- }
- <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,29,0,0" Name="listBox1" VerticalAlignment="Top" Width="154" />
- <Button Content="获取25个WebService数据" Height="23" HorizontalAlignment="Left" Margin="61,240,0,0" Name="button1" VerticalAlignment="Top" Width="154" Click="button1_Click" />
- <ListBox Height="193" HorizontalAlignment="Left" Margin="264,29,0,0" Name="listBox2" VerticalAlignment="Top" Width="154" />
- <Button Content="获取5个WebService数据" Height="23" HorizontalAlignment="Left" Margin="264,240,0,0" Name="button2" VerticalAlignment="Top" Width="154" Click="button2_Click" />
- </Grid>
- </UserControl>
- 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, 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
- }
- /// <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 下载源代码。
本文转自程兴亮 51CTO博客,原文链接:http://blog.51cto.com/chengxingliang/821967