最近项目要用到,窗体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控件。
到此这篇关于c#中backgroundworker与thread的区别的文章就介绍到这了,更多相关c# backgroundworker与thread内容请搜索以前的文章或继续浏览下面的相关文章希望大家以后多多支持!