thread学习笔记--BackgroundWorker 类
背景:
在 WinForms 中,有时要执行耗时的操作,比如统计某个磁盘分区的文件夹或者文件数目,如果分区很大或者文件过多的话,处理不好就会造成“假死”的情况,或者报“线程间操作无效”的异常,或者在该操作未完成之前操作用户界面,会导致用户界面停止响应。
----比如现在学习的MES UI中要查询数据量较大的记录显示在Spread中就可以用BackgroundWorker 类!
解决的方法就是新开一个线程,把耗时的操作放到线程中执行,这样就可以在用户界面上进行其它操作。 如果不借助Thread编程,用户就会感觉界面反映很迟钝。新建线程可以用 Thread 类,可以实现多线程同时操作,简单的可以通过 BackgroundWorker 类实现。 在.Net 2.0中可以通过BackgroundWork非常方便地进行Thread编程,
大致的步骤是:
1、调用BackgroundWorker的RunWorkerAsync方法(可以传递参数),它将引发DoWork事件
2、在DoWork的事件响应代码中调用耗时的操作,是真正的后台处理工作
3、在耗时操作中判断CancellationPending属性,如果为false则退出
4、如果要向用户界面发送信息,则调用BackgroundWorker的ReportProgress方法,它将引发ProgressChanged事件(可以将改变通过object类型传递)
5、在ProgressChanged事件的响应代码中将改变呈现给用户,及运行在主线程中
6、如果需要取消耗时操作,则调用BackgroundWorker的CancelAsync方法,需要和步骤3一起使用
命名空间:
用 BackgroundWorker 类执行耗时的操作
BackgroundWorker 类在 System.ComponentModel 命名空间下。
VS 的工具箱时有一个 BackgroundWorker 组件,就是这个类。
属性、方法和事件:
重要属性:
1、CancellationPending
获取一个值,指示应用程序是否已请求取消后台操作。通过在DoWork事件中判断CancellationPending属性可以认定是否需要取消后台操作(也就是结束线程);
2、IsBusy
获取一个值,指示 BackgroundWorker 是否正在运行异步操作。程序中使用IsBusy属性用来确定后台操作是否正在使用中;
3、WorkerReportsProgress
获取或设置一个值,该值指示BackgroundWorker能否报告进度更新
4、WorkerSupportsCancellation
获取或设置一个值,该值指示 BackgroundWorker 是否支持异步取消。设置WorkerSupportsCancellation为true使得程序可以调用CancelAsync方法提交终止挂起的后台操作的请求;
重要方法:
1、CancelAsync 请求取消挂起的后台操作
2、RunWorkerAsync 开始执行后台操作
3、ReportProgress 引发ProgressChanged事件
重要事件:
1、DoWork 调用 RunWorkerAsync 时发生
2、ProgressChanged 调用 ReportProgress 时发生
3、RunWorkerCompleted 当后台操作已完成、被取消或引发异常时发生
生命周期中的参数传递:
在整个生命周期内发生了3次重要的参数传递过程:
参数传递1:此次的参数传递是将RunWorkerAsync(Object)中的Object传递到DoWork事件的DoWorkEventArgs.Argument,由于在这里只有一个参数可以传递,所以在实际应用往封装一个类,将整个实例化的类作为RunWorkerAsync的Object传递到DoWorkEventArgs.Argument;
参数传递2:此次是将程序运行进度传递给ProgressChanged事件,实际使用中往往使用给方法和事件更新进度条或者日志信息;
参数传递3:在DoWork事件结束之前,将后台线程产生的结果数据赋给DoWorkEventArgs.Result一边在RunWorkerCompleted事件中调用RunWorkerCompletedEventArgs.Result属性取得后台线程产生的结果。
看到DoWork事件是在后台线程中运行的,所以在该事件中不能够操作用户界面的内容,如果需要更新用户界面,可以使用ProgressChanged事件及RunWorkCompleted事件来实现。
源代码:
- using System;
- using System.Collections.Generic;
- using System.ComponentModel;
- using System.Data;
- using System.Drawing;
- using System.Linq;
- using System.Text;
- using System.Windows.Forms;
- namespace WindowsFormsApp_BackGroundWorker
- {
- public partial class Form1 : Form
- {
- public Form1()
- {
- InitializeComponent();
- //设置能够报告进度更新
- //设置能够支持异步取消
- backgroundWorker1.WorkerReportsProgress = true;
- backgroundWorker1.WorkerSupportsCancellation = true;
- }
- //在designer里的属性设计器里直接双击就添加了对backgroundWorker1的ProgressChanged的事件处理程序
- //this.backgroundWorker1.DoWork += new System.ComponentModel.DoWorkEventHandler(this.backgroundWorker1_DoWork);
- //this.backgroundWorker1.ProgressChanged += new System.ComponentModel.ProgressChangedEventHandler(this.backgroundWorker1_ProgressChanged);
- //this.backgroundWorker1.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(this.backgroundWorker1_RunWorkerCompleted);
- //由ReportProgress方法触发,通过响应消息,来处理界面的显示工作
- private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
- {
- //获取异步操作进度百分比,主线程
- this.progressBar1.Value = e.ProgressPercentage;
- this.label1.Text = e.UserState.ToString();
- this.label1.Update();
- }
- //后台工作完成时引发的事件,可以在此事件处理程序里面写进行后续的处理工作,比如提示
- private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
- {
- //MessageBox.Show("计算终于完成了!");
- if (!e.Cancelled && e.Error == null)
- {
- MessageBox.Show("处理完成了!" + e.Result);
- }
- else
- {
- MessageBox.Show("后台线程被取消或发生异常!");
- }
- }
- //此事件由开始按钮里的调用RunWorkerAsync方法引发
- //这里就是后台进程开始的地方,调用工作函数的地方,也可以把现有的处理函数写在这里
- private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
- {
- // Countwork(this.backgroundWorker1);
- Countwork(backgroundWorker1);
- }
- //后台处理函数,真正的处理工作
- private bool Countwork(BackgroundWorker bw)
- {
- int n = ;
- for (int i = ; i <= n; i++)
- {
- //判断用户是否执行了取消后台操作,是的话显示返回
- if (bw.CancellationPending)
- {
- bw.ReportProgress(i,string.Format("当前操作值是{0},操作被用户申请中断",i));
- return false;
- }
- //ReportProgress函数的作用是,向主线程报告处理进度。折算成百分比,或者把进度条的最大值设置为10000
- bw.ReportProgress(i,string.Format("当前值是{0}",i));
- }
- return true;
- }
- private void button_Start_Click(object sender, EventArgs e)
- {
- //判断是否在进行异步操作,应对用户多次点击开始按钮
- if(this.backgroundWorker1.IsBusy)
- {
- return;
- }
- //触发DOWORK事件,实际就是让后台工作开始
- this.backgroundWorker1.RunWorkerAsync();
- }
- //不太好用...
- private void button_Cancel_Click(object sender, EventArgs e)
- {
- this.backgroundWorker1.CancelAsync();
- this.backgroundWorker1.Dispose();//释放资源
- }
- private void button_Exit_Click(object sender, EventArgs e)
- {
- this.Close();
- }
- }
- }
运行截图:
以上,本人的学习总结,优秀BLOG参考:
http://blog.itpub.net/23109131/viewspace-670314/
http://blog.163.com/j_yd168/blog/static/4967972820092114269195/ c# BackGroundWorker 多线程操作的小例子
thread学习笔记--BackgroundWorker 类的更多相关文章
- Java学习笔记——File类之文件管理和读写操作、下载图片
Java学习笔记——File类之文件管理和读写操作.下载图片 File类的总结: 1.文件和文件夹的创建 2.文件的读取 3.文件的写入 4.文件的复制(字符流.字节流.处理流) 5.以图片地址下载图 ...
- python学习笔记4_类和更抽象
python学习笔记4_类和更抽象 一.对象 class 对象主要有三个特性,继承.封装.多态.python的核心. 1.多态.封装.继承 多态,就算不知道变量所引用的类型,还是可以操作对象,根据类型 ...
- Java学习笔记之---类和对象
Java学习笔记之---类和对象 (一)类 类是一个模板,它描述一类对象的行为和状态 例如:动物类是一个类,动物们都有属性:颜色,动物们都有行为:吃饭 public class Dog { Stri ...
- UML学习笔记:类图
UML学习笔记:类图 有些问题,不去解决,就永远都是问题! 类图 类图(Class Diagrame)是描述类.接口以及它们之间关系的图,用来显示系统中各个类的静态结构. 类图包含2种元素:类.接口, ...
- swift学习笔记3——类、结构体、枚举
之前学习swift时的个人笔记,根据github:the-swift-programming-language-in-chinese学习.总结,将重要的内容提取,加以理解后整理为学习笔记,方便以后查询 ...
- Java学习笔记-File类的基本方法
要渐渐养成写博客的习惯-----> 前段时间看Mars的java中的I/O流没怎么懂,发现I/O流好难啊.今天重新看一遍其他教学,还有书籍,做些笔记,记录下每天的学习生活. File类的一些方法 ...
- CSS3学习笔记——伪类hover
最近看到一篇文章:“Transition.Transform和Animation使用简介及应用展示” ,想看看里面 “不同缓动类效果demo”例子的效果,发现了一个问题如下: .Trans_Bo ...
- Java7编程 高级进阶学习笔记--嵌套类
定义: 在一个类中定义的类叫做嵌套类. 作用: 1.允许对相关类进行逻辑分组 2.增强了代码的封装性 3.使代码具有更强的可读性和维护性 使用方式: package com.cmz.baseTest; ...
- 初探swift语言的学习笔记四(类对象,函数)
作者:fengsh998 原文地址:http://blog.csdn.net/fengsh998/article/details/29606137 转载请注明出处 假设认为文章对你有所帮助,请通过留言 ...
随机推荐
- 实现dropdownList 无刷新
<asp:ScriptManager ID="ScriptManager1" runat="server"> </asp:ScriptMana ...
- 从wireshark中学网络分析(一)
http://blog.csdn.net/nk_test/article/details/56509688 http://blog.csdn.net/nk_test/article/details/5 ...
- 【MyEclipse常见错误】-java.lang.NoClassDefFoundError: org/apache/juli/logging/LogFactory的解决
ApacheJavaTomcatMyeclipse 自己前一段时间出现了这个问题,通过在网上搜索,大概知道了原因,整理下一,以供大家参考. 将项目部署好后,启动tomcat后报错,java.lang ...
- 浅析C#代理
delegate 是委托声明的基础,是.net 的委托的声明的关键字action 是基于delegate实现的代理 有多个参数(无限制个数)无返回值的代理 func 是基于delegate实现的代理 ...
- cookie,session,用户认证组件
一. 绘画跟踪技术 在客户端与服务端的一次会务中,多次的请求与相应,HTTP协议是无状态协议,也就是说每个请求都是独立的!无法记录前一次请求的状态.会话跟踪技术即能够实现多次回话间信息共享的作用,HT ...
- HTML连载11-HTML中被废弃的标签&字符实体
一.为什么会有被废弃的标签 答:HTML中以前存在一部分不是用来添加语义的标签,而与我们HTML标签是用来添加语义的,这与我们的定义不相符. 例如: 1.标签<br>:换行 2.标签&l ...
- nice-validator表单验证插件的简单使用
前言 前端表单校验是过滤无效数据.假数据.有毒数据的第一步,是数据安全的第一道关卡,虽然我们不能100%相信客户端提交的数据(真正的校验还得在服务端进行),但设置前端表单校验也是至关重要的,自己写逻辑 ...
- Mount挂载/data时出现mount: /data is busy 如何解决?
1.df -h查看下挂载点/data是否正在使用,有时候会存在挂载了,但df -h不会显示出来,这时候 grep “/data” /proc/mounts 来进行查看 2.当确认挂载点/data正在使 ...
- github 上传更新代码(最简单的方法)
1.首先你需要一个github账号,还没有的朋友先去注册一个吧! GitHub地址:https://github.com/ 我们使用git需要先安装git工具,这里给出下载地址,下载后一路直接安装即可 ...
- List集合总结,对比分析ArrayList,Vector,LinkedList
前面已经写了三篇关于Java集合的文章,包括: Java集合 ArrayList原理及使用 再说Java集合,subList之于ArrayList Java集合 LinkedList的原理及使用 关于 ...