Silverlight与Websevice进行交互时,在WebSevice中可能存在耗时较长的涵数,这时候我们需要显示一个状态或进度为浏览者显示出程序目前正在处理或读取数据,使浏览者不会认为成是没响应或者是其它的异常情况,但目前许多Silverlight程序在处理这样长时间等待的情况,一般是显示一段正在装载的动画或者是一句文本提示(比如:正在装载数据,请稍候...),需要等待多少时间浏览者心里没底(有可能还会产生烦躁的情绪),要是能显示具体的完成进度,或者是显示正在处理哪方面的数据,这样来对提升客户体验会有不少的帮助。
Silverlight客户端在提交Websevice涵数后,没法直接得到涵数的完成进度,只能是通过Completed事件得知涵数已经完成,但利用这些涵数都是异步交互的特性,在Silverlight客户端建立一个定时向Websevice涵数查询的线程,便可以得知目前涵数正在处理数据的详细情况了,具体的例子代码如下,相信各位通过适当的更改一些代码,便可以完成适合自己程序的功能。
程序运行时的图片:
以下是代码:
----------------------Websevice.cs--------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Services;
using System.Threading;
[WebService(Namespace = "http://localhost:8080/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
// 若要允许使用 ASP.NET AJAX 从脚本中调用此 Web 服务,请取消对下行的注释。
// [System.Web.Script.Services.ScriptService]
public class Service : System.Web.Services.WebService
{
public Service () {
//如果使用设计的组件,请取消注释以下行
//InitializeComponent();
}
//此类用于更新或获取数据处理进度
public class cComplete {
private static int sProPerc;//处理数据进度
public void ReSet(int num)
{
sProPerc = num;
}
public int GetValue()
{
return sProPerc;
}
public void SetValue(int value)
{
sProPerc = value;
}
}
public cComplete _gcComplete = new cComplete();
[WebMethod]
public string ProData()
{
Random ra = new Random();
//此处处理耗时数据并更新处理进度
_gcComplete.ReSet(0);
for (int i = 0; i < 100; i++)
{
_gcComplete.SetValue(i);//更新进度
Thread.Sleep(ra.Next(500));
}
//********************
return "数据处理完成!";
}
//获取完成进度
[WebMethod]
public string GetCompleteNum()
{
return _gcComplete.GetValue().ToString();
}
}
----------------------Page.xaml---------------------------------------------------------
<UserControl
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"
x:Class="GetWebsevicePro.MainPage"
Width="640" Height="480" mc:Ignorable="d">
<Grid x:Name="LayoutRoot" Background="White">
<TextBlock x:Name="TxtB_Load" TextWrapping="Wrap" Margin="220,221,224,229" Width="196" Height="30" TextAlignment="Center"/>
<Button x:Name="Btn_BeginLoading" VerticalAlignment="Bottom" Content="处理数据" Margin="280,0,285,188" Click="Btn_BeginLoading_Click"/>
</Grid>
</UserControl>
--------------------------page.xaml.cs-----------------------------------------------------
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Threading;
using GetWebsevicePro.MyService;//websevice引用
namespace GetWebsevicePro
{
public partial class MainPage : UserControl
{
public MainPage()
{
// 为初始化变量所必需
InitializeComponent();
sev.ProDataCompleted += new EventHandler<ProDataCompletedEventArgs>(sev_ProDataCompleted);
sev.GetCompleteNumCompleted += new EventHandler<GetCompleteNumCompletedEventArgs>(sev_GetCompleteNumCompleted);
}
private Thread threadPro;
private bool bThreadIsOver;//线程结束标志
private ServiceSoapClient sev = new ServiceSoapClient();
private void Btn_BeginLoading_Click(object sender, System.Windows.RoutedEventArgs e)
{
// TODO: Add event handler implementation here.
Btn_BeginLoading.IsEnabled = false;
//提交需要处理数据
sev.ProDataAsync();
//开启读取Websevice数据处理进度线程
bThreadIsOver = false;
threadPro = new Thread(thread_Begin);
threadPro.Start();
}
//数据处理完成
void sev_ProDataCompleted(object sender, ProDataCompletedEventArgs e)
{
//throw new NotImplementedException();
bThreadIsOver = true;
TxtB_Load.Text = e.Result;
Btn_BeginLoading.IsEnabled = true;
}
//处理数据进度线程
void thread_Begin()
{
int sleepNum = 500;//0.5秒更新
while (!bThreadIsOver)
{
sev.GetCompleteNumAsync();
Thread.Sleep(sleepNum);
}
}
//每次完成进度读取
void sev_GetCompleteNumCompleted(object sender, GetCompleteNumCompletedEventArgs e)
{
//throw new NotImplementedException();
if (!bThreadIsOver)
{
//线程内委托
this.Dispatcher.BeginInvoke(() => {
TxtB_Load.Text = "正在处理..." + e.Result + "%";
});
}
}
}
}