C#中Backgroundworker與Thread的區(qū)別
最近項(xiàng)目要用到,窗體Form程序要在后臺(tái)開啟幾個(gè)子線程,負(fù)責(zé)和其他端進(jìn)行通信,異步讀寫,并且來(lái)更改UI。在網(wǎng)上查了有Backgroundworker與Thread兩種方法。
1.Backgroundworker
BackgroundWorker是微軟的在.net Framwork中添加的一個(gè)組件,主要對(duì)線程的訪問(wèn)提供了一種安全的方式。簡(jiǎn)單的說(shuō)就是對(duì)Thread的一次封裝。
首先介紹一下BackgroundWorker的相關(guān)屬性和方法:
屬性:
- WorkerReportsProgress:是否可以報(bào)告進(jìn)度。
- WorkerSupportsCancellation:是否允許異步中止。
- IsBusy:是否在運(yùn)行。
- CancellationPending:判斷BackgroundWorker是否已經(jīng)異步取消。
方法:
- RunWorkerAsync:開始執(zhí)行任務(wù)。觸發(fā)DoWork事件
- ReportProgress:異步提醒,觸發(fā)ProgressChanged事件,但是這個(gè)如果可以使用,必須設(shè)置WorkerReportsProgress為True
- CancelAsync:取消BackgroundWorker操作。
事件:
- DoWork:執(zhí)行RunWorkerAsync后觸發(fā),異步執(zhí)行的認(rèn)為。
- ProgressChanged:執(zhí)行ReportProgress時(shí)觸發(fā),異步獲得進(jìn)度。
- RunWorkerCompleted:線程結(jié)束時(shí)觸發(fā),主要有成功結(jié)束,發(fā)生異?;蛘呷∠麜r(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ō),需要寫委托,代碼量是很多,但是對(duì)于BackgroundWorker來(lái)說(shuō),卻沒有線程暫停和繼續(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ù)雜控制(如線程同步)時(shí),要自己 創(chuàng)建線程。畢竟,如果我們要實(shí)用多個(gè)線程,還需要往窗體中加好幾個(gè)BackgroundWorker控件。
到此這篇關(guān)于C#中Backgroundworker與Thread的區(qū)別的文章就介紹到這了,更多相關(guān)C# Backgroundworker與Thread內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Graphics.DrawImage繪制的圖像變大的原因分析及解決
這篇文章主要介紹了Graphics.DrawImage繪制的圖像變大的原因分析及解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-11-11
WPF+ASP.NET SignalR實(shí)現(xiàn)后臺(tái)通知功能的示例代碼
本文以一個(gè)簡(jiǎn)單示例,簡(jiǎn)述如何通過(guò)WPF+ASP.NET SignalR實(shí)現(xiàn)消息后臺(tái)通知以及數(shù)據(jù)的實(shí)時(shí)刷新,僅供學(xué)習(xí)分享使用,如有不足之處,還請(qǐng)指正2022-09-09
unity3D實(shí)現(xiàn)三維物體跟隨鼠標(biāo)
這篇文章主要為大家詳細(xì)介紹了unity3D實(shí)現(xiàn)三維物體跟隨鼠標(biāo),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-12-12
C# datatable 不能通過(guò)已刪除的行訪問(wèn)該行的信息處理方法
采用datatable.Rows[i].Delete()刪除行后再訪問(wèn)該表時(shí)出現(xiàn)出現(xiàn)“不能通過(guò)已刪除的行訪問(wèn)該行的信息”的錯(cuò)誤2012-11-11
解析C#網(wǎng)絡(luò)編程中的Http請(qǐng)求
這篇文章主要介紹了C#網(wǎng)絡(luò)編程中的Http請(qǐng)求,不過(guò)這次也使我對(duì)C#網(wǎng)絡(luò)編程了解的更多,算是一次學(xué)習(xí)經(jīng)歷吧,文章結(jié)合示例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下2022-03-03
C#遠(yuǎn)程發(fā)送和接收數(shù)據(jù)流生成圖片的方法
這篇文章主要介紹了C#遠(yuǎn)程發(fā)送和接收數(shù)據(jù)流生成圖片的方法,涉及C#通過(guò)數(shù)據(jù)流傳輸圖片的相關(guān)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-07-07
Unity編輯器資源導(dǎo)入處理函數(shù)OnPostprocessAudio使用案例
這篇文章主要為大家介紹了Unity編輯器資源導(dǎo)入處理函數(shù)OnPostprocessAudio使用案例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-08-08

