Silverlight实用窍门系列:21.循环访问WebService方法来看Silverlight下WebService异步请求【附带源码实例】...

        问题:笔者在项目中需要循环一个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数据排列不同可以看出:发出请求的时间顺序和得到结果的时间顺序是不一致的。

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

2011030815160661.jpg

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

ContractedBlock.gif ExpandedBlockStart.gif 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;
}
}
}
ContractedBlock.gif ExpandedBlockStart.gif 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,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 >
ContractedBlock.gif ExpandedBlockStart.gif 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, 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 下载源代码。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值