Silverlight实用窍门系列:24.Silverlight多线程技术BackgroundWorker的应用,更新ProgressBar控件【附带源码实例】

简介:

 在Silverlight中极其耗时的操作会导致UI进程假死,如果将复杂的操作和UI显示分离开而且我们需要了解这复杂操作的后台进程当前运行的进度如何?这里我们可以使用BackgroundWorker来解决这个问题。

        BackgroundWorker是一个封装了的Thread组件,它能够让用户方便的开启一个独立的线程执行复杂和耗时的后台工作,随时报告当前完成程度,随时中止异步线程操作,还可以在异步操作状态报告中(ProgressChanged)和异步操作完成后(RunWorkerCompleted)的响应事件中访问UI线程。

        BackgroundWorker的一些常用的属性、方法和事件如下:

         •属性

             CancellationPending  获取一个值,指示应用程序是否已请求取消后台操作。 
             IsBusy  获取一个值,指示 BackgroundWorker 是否正在运行异步操作。 
             WorkerReportsProgress  获取或设置一个值,该值指示 BackgroundWorker 能否支持报告进度更新。 
             WorkerSupportsCancellation  获取或设置一个值,该值指示 BackgroundWorker 是否支持异步取消。

         •方法

             CancelAsync  请求取消挂起的后台操作。  
             ReportProgress   引发 ProgressChanged 事件。  
             RunWorkerAsync  开始执行后台操作。
  
          •事件

             DoWork  调用 RunWorkerAsync 时发生。 
             ProgressChanged  调用 ReportProgress 时发生。 
             RunWorkerCompleted  当后台操作已完成、被取消或引发异常时发生。

        现在我们清理一下这个组件的运行思路:

        一、首先我们创建一个BackgroundWorker对象实例,然后设置它的属性WorkerReportsProgress、WorkerSupportsCancellation为ture,为BackgroundWorker实例的DoWork 、ProgressChanged 、RunWorkerCompleted 三个事件加载相应的事件处理方法。

        二、此时按下“运行按钮”,根据BackgroundWorker的IsBusy属性判断当前对象是否已经正在开始执行后台异步线程,如果未执行异步线程,则调用RunWorkerAsync()方法开始执行异步线程并且可以传递参数A,此时将触发DoWork事件,在这个事件内部是不能直接操作UI线程的。此时在DoWork响应时间内部首先判断CancellationPending属性是否为ture,如果为true表示当前已经取消异步进程运行,否则继续运行需要处理的复杂运算,可以通过e.Argument属性接收到参数A。

        三、在运行复杂运算的过程中,每隔一个时间段执行一次ReportProgress(int percentProgress)函数,传递当前运行完成百分数,此时为参数B,然后触发ProgressChanged事件,在此事件中通过e.ProgressPercentage属性接收到参数B,更新UI的ProgressBar控件,显示当前的完成进度。

        四、当DoWork内的复杂运算完毕之后为当前DoWork事件的e.Result赋值C,再触发RunWorkerCompleted 事件,此时在RunWorkerCompleted 事件中接受e.Result的值。将结果显示到UI界面上即可。

        下面我们来看一段实例程序源码MainPage.xaml.cs,相关的运行注释在代码中已经注明:

复制代码

  
  
public partial class MainPage : UserControl
{
// 声明一个BackgroundWorker对象实例
private BackgroundWorker bgWorker = new BackgroundWorker();
public MainPage()
{
InitializeComponent();
InitBackGroundWorker();
}
// 初始化BackgroundWorker的相关属性和加载事件
public void InitBackGroundWorker()
{
// BackgroundWorker是否支持报告执行进度
bgWorker.WorkerReportsProgress = true ;
// BackgroundWorker是否支持取消运行异步操作
bgWorker.WorkerSupportsCancellation = true ;
// 加载DoWork、ProgressChanged、RunWorkerCompleted事件
bgWorker.DoWork += new DoWorkEventHandler(bgWorker_DoWork);
bgWorker.ProgressChanged
+= new ProgressChangedEventHandler(bgWorker_ProgressChanged);
bgWorker.RunWorkerCompleted
+= new RunWorkerCompletedEventHandler(bgWorker_RunWorkerCompleted);
}
// 后台异步执行操作的地方
void bgWorker_DoWork( object sender, DoWorkEventArgs e)
{
// 获取到传递进来的参数
string str = e.Argument.ToString();
// 执行100次循环
for ( int i = 0 ; i < 100 ; i ++ )
{
// 判断当前BackgroundWorker是否已经被取消了异步操作
if (bgWorker.CancellationPending == false )
{
// 如果没有被取消异步操作,则线程阻塞以下,然后报告给bgWorker_ProgressChanged事件
Thread.Sleep( 50 );
bgWorker.ReportProgress(i
+ 1 );
e.Result
= " 3322 " ;
}
else
{
// 设置当前已取消异步线程操作
e.Cancel = true ;
break ;
}
}
}
// 进度改变时触发的事件执行函数,这里显示执行进度
void bgWorker_ProgressChanged( object sender, ProgressChangedEventArgs e)
{
// 设置当前进度条的值为事件执行完成程度值
this .progressBar1.Value = e.ProgressPercentage;
}
// 异步操作执行完毕之后的处理
void bgWorker_RunWorkerCompleted( object sender, RunWorkerCompletedEventArgs e)
{

// 完成异步操作之后检查是否取消了异步操作,弹出相关提示
if (e.Cancelled == true )
{
MessageBox.Show(
" 取消异步线程操作 " );
}
else
{
MessageBox.Show(
" 异步线程执行完毕 " + e.Result);
}

this .btncancel.Content = " 已完成 " ;
}

private void btnrun_Click( object sender, RoutedEventArgs e)
{
// 如果后台进程未开始运行,则开始运行线程
if (bgWorker.IsBusy != true )
{
bgWorker.RunWorkerAsync(
" 我是参数 " );
}
}

private void btncancel_Click( object sender, RoutedEventArgs e)
{
// 取消异步操作。
bgWorker.CancelAsync();
}
}
复制代码

        本实例采用VS2010+Silverlight 4.0编写,点击 SLBackgroundWorker_Caleung.rar 下载本实例源码。



    本文转自程兴亮博客园博客,原文链接:http://www.cnblogs.com/chengxingliang/archive/2011/03/11/1981623.html,如需转载请自行联系原作者

相关文章
Silverlight自定义数据绑定控件应该如何处理IEditableObject和IEditableCollectionView对象
原文:Silverlight自定义数据绑定控件应该如何处理IEditableObject和IEditableCollectionView对象 原创文章,如需转载,请注明出处。   最近在一直研究Silverlight下的数据绑定控件,发现有这样两个接口IEditableObject 和IEditableCollectionView,记录一下结论,欢迎交流指正。
869 0
|
容器
使用MEF构建可扩展的Silverlight应用
“托管扩展性框架(Managed Extensibility Framework,简称MEF),是微软.NET框架下为提高应用和组件复用程度而推出的,用于使组件能够最大化的重用。使用MEF能够使静态编译的.NET应用程序转换为动态组合,这将是创建可扩展应用、可扩展框架和应用扩展的好途径。
739 0
|
1月前
|
存储 消息中间件 资源调度
C++ 多线程之初识多线程
这篇文章介绍了C++多线程的基本概念,包括进程和线程的定义、并发的实现方式,以及如何在C++中创建和管理线程,包括使用`std::thread`库、线程的join和detach方法,并通过示例代码展示了如何创建和使用多线程。
38 1
C++ 多线程之初识多线程