C#中Backgroundworker與Thread的區(qū)別
最近項(xiàng)目要用到,窗體Form程序要在后臺(tái)開(kāi)啟幾個(gè)子線(xiàn)程,負(fù)責(zé)和其他端進(jìn)行通信,異步讀寫(xiě),并且來(lái)更改UI。在網(wǎng)上查了有Backgroundworker與Thread兩種方法。
1.Backgroundworker
BackgroundWorker是微軟的在.net Framwork中添加的一個(gè)組件,主要對(duì)線(xiàn)程的訪(fǎng)問(wèn)提供了一種安全的方式。簡(jiǎn)單的說(shuō)就是對(duì)Thread的一次封裝。
首先介紹一下BackgroundWorker的相關(guān)屬性和方法:
屬性:
- WorkerReportsProgress:是否可以報(bào)告進(jìn)度。
- WorkerSupportsCancellation:是否允許異步中止。
- IsBusy:是否在運(yùn)行。
- CancellationPending:判斷BackgroundWorker是否已經(jīng)異步取消。
方法:
- RunWorkerAsync:開(kāi)始執(zhí)行任務(wù)。觸發(fā)DoWork事件
- ReportProgress:異步提醒,觸發(fā)ProgressChanged事件,但是這個(gè)如果可以使用,必須設(shè)置WorkerReportsProgress為T(mén)rue
- CancelAsync:取消BackgroundWorker操作。
事件:
- DoWork:執(zhí)行RunWorkerAsync后觸發(fā),異步執(zhí)行的認(rèn)為。
- ProgressChanged:執(zhí)行ReportProgress時(shí)觸發(fā),異步獲得進(jìn)度。
- RunWorkerCompleted:線(xiàn)程結(jié)束時(shí)觸發(fā),主要有成功結(jié)束,發(fā)生異常或者取消時(shí)發(fā)生。
一個(gè)簡(jiǎn)單的例子:
public partial class MainWindow : Window { private BackgroundWorker m_BackgroundWorker;// 申明后臺(tái)對(duì)象 public MainWindow() { InitializeComponent(); m_BackgroundWorker = new BackgroundWorker(); // 實(shí)例化后臺(tái)對(duì)象 m_BackgroundWorker.WorkerReportsProgress = true; // 設(shè)置可以通告進(jìn)度 m_BackgroundWorker.WorkerSupportsCancellation = true; // 設(shè)置可以取消 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就是一個(gè)高級(jí)控件,方便使用Thread,后者是前者的靈魂或基礎(chǔ)
直接使用后者難度稍大,但換來(lái)的是靈活方便。
Thread的使用就比較麻煩了,對(duì)于尤其是對(duì)異步提醒來(lái)說(shuō),需要寫(xiě)委托,代碼量是很多,但是對(duì)于BackgroundWorker來(lái)說(shuō),卻沒(méi)有線(xiàn)程暫停和繼續(xù)的方法。但是對(duì)于一般的來(lái)說(shuō),這些功能也是不用的,而且在微軟的文檔中還提到了,Thread的Resume和Suspend已經(jīng)不推薦使用。
一個(gè)簡(jiǎn)單的例子:
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());//觸發(fā)事件 } } } } 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.總結(jié)
當(dāng)你執(zhí)行的任務(wù)較簡(jiǎn)單,不需要復(fù)雜控制時(shí)使用BackgroundWorker,較為方便;當(dāng)你要執(zhí)行的任務(wù)需要復(fù)雜控制(如線(xiàn)程同步)時(shí),要自己 創(chuàng)建線(xiàn)程。畢竟,如果我們要實(shí)用多個(gè)線(xiàn)程,還需要往窗體中加好幾個(gè)BackgroundWorker控件。
到此這篇關(guān)于C#中Backgroundworker與Thread的區(qū)別的文章就介紹到這了,更多相關(guān)C# Backgroundworker與Thread內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C# byte數(shù)組與Image相互轉(zhuǎn)換的方法
這篇文章介紹了C# byte數(shù)組與Image相互轉(zhuǎn)換的方法,有需要的朋友可以參考一下2013-10-10自定義實(shí)現(xiàn)Json字符串向C#對(duì)象轉(zhuǎn)變的方法
自定義實(shí)現(xiàn)Json字符串向C#對(duì)象轉(zhuǎn)變的方法,需要的朋友可以參考一下2013-03-03C#實(shí)現(xiàn)單例模式的6種方法小結(jié)
這篇文章主要介紹了C#實(shí)現(xiàn)單例模式的6種方法,C#中實(shí)現(xiàn)單例有很多種方法,本文將按順序介紹非線(xiàn)程安全、完全懶漢式、線(xiàn)程安全和低/高性能集中版本,需要的朋友可以參考下2022-09-09C# 批量生成隨機(jī)密碼必須包含數(shù)字和字母并用加密算法加密
這篇文章主要介紹了C# 批量生成隨機(jī)密碼必須包含數(shù)字和字母并用加密算法加密,需要的朋友參考下2017-01-01C#實(shí)現(xiàn)簡(jiǎn)易計(jì)算器小功能
這篇文章主要為大家詳細(xì)介紹了C#實(shí)現(xiàn)簡(jiǎn)易計(jì)算器小功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-01-01C#操作LINQ to SQL組件進(jìn)行數(shù)據(jù)庫(kù)建模的基本教程
這篇文章主要介紹了C#操作LINQ to SQL組件進(jìn)行數(shù)據(jù)庫(kù)建模的基本教程,LINQ to SQL被集成在.NET框架之中,需要的朋友可以參考下2016-03-03