C# Backgroundworker与Thread
qq_16739693 人气:0最近项目要用到,窗体Form程序要在后台开启几个子线程,负责和其他端进行通信,异步读写,并且来更改UI。在网上查了有Backgroundworker与Thread两种方法。
1.Backgroundworker
BackgroundWorker是微软的在.net Framwork中添加的一个组件,主要对线程的访问提供了一种安全的方式。简单的说就是对Thread的一次封装。
首先介绍一下BackgroundWorker的相关属性和方法:
属性:
- WorkerReportsProgress:是否可以报告进度。
- WorkerSupportsCancellation:是否允许异步中止。
- IsBusy:是否在运行。
- CancellationPending:判断BackgroundWorker是否已经异步取消。
方法:
- RunWorkerAsync:开始执行任务。触发DoWork事件
- ReportProgress:异步提醒,触发ProgressChanged事件,但是这个如果可以使用,必须设置WorkerReportsProgress为True
- CancelAsync:取消BackgroundWorker操作。
事件:
- DoWork:执行RunWorkerAsync后触发,异步执行的认为。
- ProgressChanged:执行ReportProgress时触发,异步获得进度。
- RunWorkerCompleted:线程结束时触发,主要有成功结束,发生异常或者取消时发生。
一个简单的例子:
public partial class MainWindow : Window { private BackgroundWorker m_BackgroundWorker;// 申明后台对象 public MainWindow() { InitializeComponent(); m_BackgroundWorker = new BackgroundWorker(); // 实例化后台对象 m_BackgroundWorker.WorkerReportsProgress = true; // 设置可以通告进度 m_BackgroundWorker.WorkerSupportsCancellation = true; // 设置可以取消 m_BackgroundWorker.DoWork += new DoWorkEventHandler(DoWork); m_BackgroundWorker.ProgressChanged += new ProgressChangedEventHandler(UpdateProgress); m_BackgroundWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(CompletedWork); m_BackgroundWorker.RunWorkerAsync(this); } void DoWork(object sender, DoWorkEventArgs e) { BackgroundWorker bw = sender as BackgroundWorker; MainWindow win = e.Argument as MainWindow; int i = 0; while ( i <= 100 ) { if (bw.CancellationPending) { e.Cancel = true; break; } bw.ReportProgress(i++); Thread.Sleep(1000); } } void UpdateProgress(object sender, ProgressChangedEventArgs e) { int progress = e.ProgressPercentage; label1.Content = string.Format("{0}",progress); } void CompletedWork(object sender, RunWorkerCompletedEventArgs e) { if ( e.Error != null) { MessageBox.Show("Error"); } else if (e.Cancelled) { MessageBox.Show("Canceled"); } else { MessageBox.Show("Completed"); } } private void button1_Click(object sender, RoutedEventArgs e) { m_BackgroundWorker.CancelAsync(); } }
2.Thread
BackgroundWorker就是一个高级控件,方便使用Thread,后者是前者的灵魂或基础
直接使用后者难度稍大,但换来的是灵活方便。
Thread的使用就比较麻烦了,对于尤其是对异步提醒来说,需要写委托,代码量是很多,但是对于BackgroundWorker来说,却没有线程暂停和继续的方法。但是对于一般的来说,这些功能也是不用的,而且在微软的文档中还提到了,Thread的Resume和Suspend已经不推荐使用。
一个简单的例子:
using System; using System.Threading; namespace ThreadsComm { public delegate void ReadParamEventHandler(string sParam); class MyThread { public Thread thread1; private static ReadParamEventHandler OnReadParamEvent; public MyThread() { thread1 = new Thread(new ThreadStart(MyRead)); thread1.IsBackground = true; thread1.Start(); } public event ReadParamEventHandler ReadParam { add { OnReadParamEvent += new ReadParamEventHandler(value);} remove{ OnReadParamEvent -= new ReadParamEventHandler(value);} } protected void MyRead() { int i = 0; while (true) { Thread.Sleep(1000); i = i + 1; OnReadParamEvent(i.ToString());//触发事件 } } } } using System; using System.Windows.Forms; namespace ThreadsComm { public partial class Form1 : Form { private static string param = ""; public Form1() { InitializeComponent(); MyThread thread1 = new MyThread(); thread1.ReadParam += this.OnRead; } private void OnRead(string sParam) { param = sParam; Object[] list = { this,System.EventArgs.Empty}; this.lblShow.BeginInvoke(new EventHandler(LabelShow), list); } protected void LabelShow(Object o, EventArgs e) { this.lblShow.Text = param; } } }
3.总结
当你执行的任务较简单,不需要复杂控制时使用BackgroundWorker,较为方便;当你要执行的任务需要复杂控制(如线程同步)时,要自己 创建线程。毕竟,如果我们要实用多个线程,还需要往窗体中加好几个BackgroundWorker控件。
加载全部内容