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,相关的运行注释在代码中已经注明:

 


 
 
  1. public partial class MainPage : UserControl 
  2. //声明一个BackgroundWorker对象实例 
  3. private BackgroundWorker bgWorker = new BackgroundWorker(); 
  4. public MainPage() 
  5. InitializeComponent(); 
  6. InitBackGroundWorker(); 
  7. //初始化BackgroundWorker的相关属性和加载事件 
  8. public void InitBackGroundWorker() 
  9. //BackgroundWorker是否支持报告执行进度 
  10. bgWorker.WorkerReportsProgress = true
  11. //BackgroundWorker是否支持取消运行异步操作 
  12. bgWorker.WorkerSupportsCancellation = true
  13. //加载DoWork、ProgressChanged、RunWorkerCompleted事件 
  14. bgWorker.DoWork += new DoWorkEventHandler(bgWorker_DoWork); 
  15. bgWorker.ProgressChanged += new ProgressChangedEventHandler(bgWorker_ProgressChanged); 
  16. bgWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bgWorker_RunWorkerCompleted); 
  17. //后台异步执行操作的地方 
  18. void bgWorker_DoWork(object sender, DoWorkEventArgs e) 
  19. //获取到传递进来的参数 
  20. string str = e.Argument.ToString(); 
  21. //执行100次循环 
  22. for (int i = 0; i < 100; i++) 
  23. //判断当前BackgroundWorker是否已经被取消了异步操作 
  24. if (bgWorker.CancellationPending == false
  25. //如果没有被取消异步操作,则线程阻塞以下,然后报告给bgWorker_ProgressChanged事件 
  26. Thread.Sleep(50); 
  27. bgWorker.ReportProgress(i + 1); 
  28. e.Result = "3322"
  29. else 
  30. //设置当前已取消异步线程操作 
  31. e.Cancel = true
  32. break; 
  33. //进度改变时触发的事件执行函数,这里显示执行进度 
  34. void bgWorker_ProgressChanged(object sender, ProgressChangedEventArgs e) 
  35. //设置当前进度条的值为事件执行完成程度值 
  36. this.progressBar1.Value = e.ProgressPercentage; 
  37. //异步操作执行完毕之后的处理 
  38. void bgWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
  39.  
  40. //完成异步操作之后检查是否取消了异步操作,弹出相关提示 
  41. if (e.Cancelled == true
  42. MessageBox.Show("取消异步线程操作"); 
  43. else 
  44. MessageBox.Show("异步线程执行完毕" + e.Result); 
  45.  
  46. this.btncancel.Content = "已完成"
  47.  
  48. private void btnrun_Click(object sender, RoutedEventArgs e) 
  49. //如果后台进程未开始运行,则开始运行线程 
  50. if (bgWorker.IsBusy != true
  51. bgWorker.RunWorkerAsync("我是参数"); 
  52.  
  53. private void btncancel_Click(object sender, RoutedEventArgs e) 
  54. //取消异步操作。 
  55. bgWorker.CancelAsync(); 

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


本文转自程兴亮 51CTO博客,原文链接:http://blog.51cto.com/chengxingliang/821973

相关文章
|
25天前
|
缓存 Java 开发者
Java多线程并发编程:同步机制与实践应用
本文深入探讨Java多线程中的同步机制,分析了多线程并发带来的数据不一致等问题,详细介绍了`synchronized`关键字、`ReentrantLock`显式锁及`ReentrantReadWriteLock`读写锁的应用,结合代码示例展示了如何有效解决竞态条件,提升程序性能与稳定性。
103 6
|
23天前
|
监控 Java 数据库连接
Java线程管理:守护线程与用户线程的区分与应用
在Java多线程编程中,线程可以分为守护线程(Daemon Thread)和用户线程(User Thread)。这两种线程在行为和用途上有着明显的区别,了解它们的差异对于编写高效、稳定的并发程序至关重要。
29 2
|
28天前
|
数据采集 存储 数据处理
Python中的多线程编程及其在数据处理中的应用
本文深入探讨了Python中多线程编程的概念、原理和实现方法,并详细介绍了其在数据处理领域的应用。通过对比单线程与多线程的性能差异,展示了多线程编程在提升程序运行效率方面的显著优势。文章还提供了实际案例,帮助读者更好地理解和掌握多线程编程技术。
|
28天前
|
存储 监控 安全
深入理解ThreadLocal:线程局部变量的机制与应用
在Java的多线程编程中,`ThreadLocal`变量提供了一种线程安全的解决方案,允许每个线程拥有自己的变量副本,从而避免了线程间的数据竞争。本文将深入探讨`ThreadLocal`的工作原理、使用方法以及在实际开发中的应用场景。
54 2
|
1月前
|
安全 Java 开发者
Java 多线程并发控制:深入理解与实战应用
《Java多线程并发控制:深入理解与实战应用》一书详细解析了Java多线程编程的核心概念、并发控制技术及其实战技巧,适合Java开发者深入学习和实践参考。
54 6
|
1月前
|
存储 安全 Java
Java多线程编程中的并发容器:深入解析与实战应用####
在本文中,我们将探讨Java多线程编程中的一个核心话题——并发容器。不同于传统单一线程环境下的数据结构,并发容器专为多线程场景设计,确保数据访问的线程安全性和高效性。我们将从基础概念出发,逐步深入到`java.util.concurrent`包下的核心并发容器实现,如`ConcurrentHashMap`、`CopyOnWriteArrayList`以及`BlockingQueue`等,通过实例代码演示其使用方法,并分析它们背后的设计原理与适用场景。无论你是Java并发编程的初学者还是希望深化理解的开发者,本文都将为你提供有价值的见解与实践指导。 --- ####
|
2月前
|
存储 并行计算 安全
C++多线程应用
【10月更文挑战第29天】C++ 中的多线程应用广泛,常见场景包括并行计算、网络编程中的并发服务器和图形用户界面(GUI)应用。通过多线程可以显著提升计算速度和响应能力。示例代码展示了如何使用 `pthread` 库创建和管理线程。注意事项包括数据同步与互斥、线程间通信和线程安全的类设计,以确保程序的正确性和稳定性。
|
2月前
|
监控 Java
在实际应用中选择线程异常捕获方法的考量
【10月更文挑战第15天】选择最适合的线程异常捕获方法需要综合考虑多种因素。没有一种方法是绝对最优的,需要根据具体情况进行权衡和选择。在实际应用中,还需要不断地实践和总结经验,以提高异常处理的效果和程序的稳定性。
30 3
|
2月前
|
调度 Android开发 开发者
构建高效Android应用:探究Kotlin多线程优化策略
【10月更文挑战第11天】本文探讨了如何在Kotlin中实现高效的多线程方案,特别是在Android应用开发中。通过介绍Kotlin协程的基础知识、异步数据加载的实际案例,以及合理使用不同调度器的方法,帮助开发者提升应用性能和用户体验。
64 4
|
2月前
|
数据采集 存储 Java
Crawler4j在多线程网页抓取中的应用
Crawler4j在多线程网页抓取中的应用