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 下载本实例源码。

2011031116594790.jpg



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

相关文章
|
2月前
|
NoSQL 数据处理 调度
【Redis深度专题】「踩坑技术提升」探索Redis 6.0为何必须启用多线程以提升性能与效率
【Redis深度专题】「踩坑技术提升」探索Redis 6.0为何必须启用多线程以提升性能与效率
247 0
|
4天前
|
存储 缓存 前端开发
Java串口通信技术探究3:RXTX库线程 优化系统性能的SerialPortEventListener类
Java串口通信技术探究3:RXTX库线程 优化系统性能的SerialPortEventListener类
20 3
|
6天前
|
Dart 前端开发 安全
【Flutter前端技术开发专栏】Flutter中的线程与并发编程实践
【4月更文挑战第30天】本文探讨了Flutter中线程管理和并发编程的关键性,强调其对应用性能和用户体验的影响。Dart语言提供了`async`、`await`、`Stream`和`Future`等原生异步支持。Flutter采用事件驱动的单线程模型,通过`Isolate`实现线程隔离。实践中,可利用`async/await`、`StreamBuilder`和`Isolate`处理异步任务,同时注意线程安全和性能调优。参考文献包括Dart异步编程、Flutter线程模型和DevTools文档。
【Flutter前端技术开发专栏】Flutter中的线程与并发编程实践
|
12天前
|
缓存 Java 编译器
第一章 Java线程池技术应用
第一章 Java线程池技术应用
14 0
|
12天前
|
并行计算 算法 安全
Java从入门到精通:2.1.3深入学习Java核心技术——掌握Java多线程编程
Java从入门到精通:2.1.3深入学习Java核心技术——掌握Java多线程编程
|
13天前
|
并行计算 算法 Java
Java中的多线程技术实现与应用
【4月更文挑战第23天】本文将深入探讨Java中的多线程技术,包括其基本概念、实现方法以及在实际应用中的优势。我们将通过实例代码和应用场景,详细解析多线程技术在Java中的应用,以期帮助读者更好地理解和掌握这一技术。
|
14天前
|
Java
Java中的多线程技术实现
【4月更文挑战第22天】本文将深入探讨Java中的多线程技术实现,包括线程的创建、启动、同步和通信等方面。通过实例分析,我们将了解如何利用多线程提高程序的性能和效率。
8 2
|
16天前
|
Java
Java中的多线程技术实现
【4月更文挑战第20天】本文主要介绍了Java中的多线程技术实现,包括线程的创建、启动、同步和通信等方面。通过详细的代码示例和解析,帮助读者深入理解Java多线程技术的原理和应用。
|
1月前
|
Java API 调度
Java中的并发编程:探索多线程技术的奥秘
Java作为一种高度并发的编程语言,其多线程技术一直备受关注。本文将深入探讨Java中的并发编程,从基本概念到高级应用,解析多线程技术的奥秘,帮助读者更好地理解和应用Java中的并发编程。
|
2月前
|
程序员 开发者 Python
Python中的并发编程与多线程技术探究
Python作为一种流行的编程语言,其在并发编程方面有着独特的特点和强大的功能。本文将深入探讨Python中的并发编程技术,重点介绍多线程技术在Python中的应用与实现方式,以及如何利用多线程提高程序的性能和效率。

热门文章

最新文章