在silverlight 2(Beta1) 中使用BackgroundWorker非常简单,下面是一个DEMO,用于执行从1
累加到100.在累加过程中,SUM值会不断更新,当累加到100后,BackgroundWorker会在成功执行
结束后调用一个 WCF服务来输出最终的运行信息,就像我们在下面这张图中看到的一样.
首先我们要创建一个WCF服务应用,用来返回指定的累加数据信息.相应名称为:
CrossSiteCall_Server
因为要用到跨站调用,所以我们还要建立一个clientaccesspolicy.xml文件,并放在该项目的根目
录下,其内容如下:
<?
xml version="1.0" encoding="utf-8"
?>
<
access-policy
>
<
cross-domain-access
>
<
policy
>
<
allow-from
>
<
domain
uri
="*"
/>
</
allow-from
>
<
grant-to
>
<
resource
path
="/"
include-subpaths
="true"
/>
</
grant-to
>
</
policy
>
</
cross-domain-access
>
</
access-policy
>
下面是相应的接口(Contract)及功能代码:
[ServiceContract]
public
interface
IService
{
[OperationContract]
string
ShowMessage(
int
x,
int
y,
int
sum);
}
public
class
Service : IService
{
public
string
ShowMessage(
int
x,
int
y ,
int
sum)
{
return
"
从
"
+
x
+
"
累加到
"
+
y
+
"
等于:
"
+
sum;
}
}
然后将web.config文件中的binding="wsHttpBinding" 改写成basicHttpBinding. 编译运行这个
项目,并将最终的服务引用地址复制下来.
本DEMO中的链接地址:http://localhost:7501/Service.svc
然后我们再去创建一个Silverlight Application 项目,并将其命名为:BackgroundWorker
并在当前的silverlight项目中添加上面SVC地址的服务引用,并将其命名为Service.
下面就是相应的xaml代码,将它放入Page.xaml中:
<
Grid
x:Name
="LayoutRoot"
Background
="White"
>
<
StackPanel
HorizontalAlignment
="Center"
VerticalAlignment
="Center"
>
<
TextBlock
x:Name
="txtDisplay"
FontSize
="24"
TextAlignment
="Center"
Margin
="10"
Text
="暂无内容"
/>
<
Button
x:Name
="btnRun"
Content
="从1到100累加"
Click
="OnRun"
Margin
="10"
/>
<
Button
x:Name
="btnCancel"
Content
="取 消"
Click
="OnCancel"
Margin
="10"
/>
</
StackPanel
>
</
Grid
>
接下来就是相应的cs代码了,相当的注释我已写入代码段中,相信大家看一下就会明白了:)
public
partial
class
Page : UserControl
{
private
System.ComponentModel.BackgroundWorker worker;
private
int
sum
=
0
;
//
累加数
private
int
cur_number
=
1
;
//
当前数值
void
OnRun(
object
sender, EventArgs args)
{
worker
=
new
System.ComponentModel.BackgroundWorker();
//
当前BackgroundWorker所执行的操作
worker.DoWork
+=
OnDoWork;
//
绑定异步操作进度的事件
worker.ProgressChanged
+=
OnProgressChanged;
//
绑定操作成功完成的处理事件
worker.RunWorkerCompleted
+=
OnWorkCompleted;
//
是否报告进度更新
worker.WorkerReportsProgress
=
true
;
//
是否支持异步取消
worker.WorkerSupportsCancellation
=
true
;
//
开始执行后台操作
worker.RunWorkerAsync();
}
void
OnWorkCompleted(
object
sender, RunWorkerCompletedEventArgs e)
{
if
(e.Error
!=
null
)
{
Exception ex
=
e.Error;
//
int x = 10;
}
if
(e.Cancelled)
{
txtDisplay.Text
=
"
取消!
"
;
}
else
{
txtDisplay.Text
+=
"
完毕, 开始调用WCF!
"
;
//
调用Service服务
ServiceClient proxy
=
new
ServiceClient();
proxy.ShowMessageCompleted
+=
OnShowMessageCompleted;
proxy.ShowMessageAsync(
1
,
100
, sum);
}
}
void
OnProgressChanged(
object
sender, ProgressChangedEventArgs e)
{
txtDisplay.Text
=
e.ProgressPercentage.ToString();
}
void
OnDoWork(
object
sender, DoWorkEventArgs e)
{
//
throw new ApplicationException("Foo");
while
(cur_number
<=
100
&&
!
worker.CancellationPending)
{
Thread.Sleep(
100
);
sum
+=
cur_number;
cur_number
++
;
worker.ReportProgress(sum);
}
if
(worker.CancellationPending)
{
e.Cancel
=
true
;
}
}
void
OnShowMessageCompleted(
object
sender, ShowMessageCompletedEventArgs e)
{
if
(e.Error
!=
null
)
{
txtDisplay.Text
=
"
调用失败
"
;
}
else
{
txtDisplay.Text
=
e.Result.ToString();
}
}
void
OnCancel(
object
sender, EventArgs args)
{
sum
=
0
;
cur_number
=
0
;
//
取消异步操作
worker.CancelAsync();
}
}
另外还需要在cs文件中引用一下相应的名空间如下:
using
System.ComponentModel;
//
BackgroundWorker
using
System.Threading;
using
BackgroundWorker.Service;
//
wcf引用名空间
现在就可以编译运行这个silverlight应用的(之前请先运行上面的wcf项目).
另外除了BackgroundWorker, silverlight 2目前还可以使用DispatcherTimer组件定时器来
进行一些需要定时运行的任务.详见这里:)
看来SL真是越来越强大了.
源码下载,请点击这里:)