.NET跨線(xiàn)程控件的相關(guān)操作是什么,針對(duì)這個(gè)問(wèn)題,這篇文章詳細(xì)介紹了相對(duì)應(yīng)的分析和解答,希望可以幫助更多想解決這個(gè)問(wèn)題的小伙伴找到更簡(jiǎn)單易行的方法。
專(zhuān)注于為中小企業(yè)提供成都網(wǎng)站建設(shè)、網(wǎng)站建設(shè)服務(wù),電腦端+手機(jī)端+微信端的三站合一,更高效的管理,為中小企業(yè)新余免費(fèi)做網(wǎng)站提供優(yōu)質(zhì)的服務(wù)。我們立足成都,凝聚了一批互聯(lián)網(wǎng)行業(yè)人才,有力地推動(dòng)了近千家企業(yè)的穩(wěn)健成長(zhǎng),幫助中小企業(yè)通過(guò)網(wǎng)站建設(shè)實(shí)現(xiàn)規(guī)模擴(kuò)充和轉(zhuǎn)變。
在.NET中,如果我們?cè)诜荱I線(xiàn)程上訪(fǎng)問(wèn)窗體上的控件的時(shí)候,會(huì)產(chǎn)生一個(gè)跨線(xiàn)程調(diào)用的異常,那么如何處理這種情況呢?我介紹了使用Control.Invoke方法,如果你不習(xí)慣使用委托,那么.Net還為我們提供了一個(gè)組件BackgroundWorker,你可以使用這個(gè)組件,以事件的方式去處理這種跨線(xiàn)程的控件訪(fǎng)問(wèn)。下面我就來(lái)詳細(xì)的介紹一下這個(gè)組件的用法。
我們先來(lái)看一下BackgroundWorker提供了哪些常用的成員,
事件
◆DoWork:我們?cè)谶@個(gè)事件中,執(zhí)行需要異步處理的工作。
◆ProgressChanged:我們?cè)谶@個(gè)事件中,接收并處理異步處理過(guò)程中的信息。
◆RunWorkerCompleted:我們?cè)谶@個(gè)事件中,執(zhí)行異步處理結(jié)束的工作。
方法
◆RunWorkerAsync()和RunWorkerAsync(object argument):這兩個(gè)方法觸發(fā)DoWork事件,開(kāi)始異步操作。
◆ReportProgress(int percentProgress)和ReportProgress(int percentProgress, object userState):這兩個(gè)方法觸發(fā)ProgressChanged事件。
◆CancelAsync:結(jié)束后臺(tái)的異步操作。
屬性
◆bool CancellationPending:指示當(dāng)前的后臺(tái)的異步操作是否正在被取消,執(zhí)行CancelAsync方法會(huì)導(dǎo)致這個(gè)屬性為true。
◆bool IsBusy:指示當(dāng)前的后臺(tái)異步操作是否正在進(jìn)行,進(jìn)行中為true。
◆bool WorkerReportsProgress:獲取或設(shè)置當(dāng)前的BackgroundWorker是否可以執(zhí)行ProgressChanged方法。
◆bool WorkerSupportsCancellation:獲取或設(shè)置當(dāng)前的BackgroundWorker是否可以執(zhí)行CancelAsync方法。
OK,有了上面這些成員,我們來(lái)看一下BackgroundWorker是如何工作的。
Step 1. 當(dāng)然是定義一個(gè)BackgroundWorker的實(shí)例,你可以從工具箱中拖拽一個(gè)BackgroundWorker控件到窗體上或者在代碼中直接聲明;
Step 2. 生成DoWork事件并在DoWork事件的中添加需要異步執(zhí)行的代碼。在異步執(zhí)行的代碼中,如果需要處理界面中的控件,請(qǐng)調(diào)用ReportProgress方法,而不要直接處理(例如給控件賦值),因?yàn)镈oWork事件跟正常的界面的事件不同,這個(gè)事件在非UI線(xiàn)程上執(zhí)行,所以才能異步執(zhí)行。
Step 3. 生成ProgressChanged事件并添加控件處理的代碼,因?yàn)檫@個(gè)事件是在UI線(xiàn)程上執(zhí)行的,所以可以給界面中的控件進(jìn)行賦值等操作。
Step 4. 如果需要,請(qǐng)生成RunWorkerCompleted事件,在此處理異步執(zhí)行結(jié)束的業(yè)務(wù)邏輯。當(dāng)然,此事件也是在UI線(xiàn)程上執(zhí)行的,可以給界面中的控件進(jìn)行賦值等操作。
Step 5. 在需要執(zhí)行異步操作的地方調(diào)用RunWorkerAsync方法,開(kāi)始執(zhí)行異步調(diào)用。
下面是具體的代碼:
public Form1() { InitializeComponent(); bWorker.DoWork += new DoWorkEventHandler(bWorker_DoWork); bWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bWorker_RunWorkerCompleted); bWorker.ProgressChanged += new ProgressChangedEventHandler(bWorker_ProgressChanged); this.Text = "UI thread id is:" + Thread.CurrentThread.ManagedThreadId.ToString(); } BackgroundWorker bWorker = new BackgroundWorker(); void bWorker_DoWork(object sender, DoWorkEventArgs e) { int tick = (int)e.Argument; Thread thr = Thread.CurrentThread; for (int i = 0; i < 30; i++) { if (bWorker.CancellationPending) { e.Cancel = true; //break; } else { Thread.Sleep(TimeSpan.FromSeconds(tick)); bWorker.ReportProgress(i, DateTime.Now.ToString() + "\\TID:" + thr.ManagedThreadId.ToString()); } } } void bWorker_ProgressChanged(object sender, ProgressChangedEventArgs e) { progressBar1.Value = e.ProgressPercentage; label1.Text = e.UserState.ToString(); } void bWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { label1.Text = DateTime.Now.ToString(); progressBar1.Value = progressBar1.Maximum; if (e.Cancelled) label1.Text = "User cancelled."; } private void btnInvoke_Click(object sender, EventArgs e) { bWorker.WorkerReportsProgress = true; bWorker.WorkerSupportsCancellation = true; if (!bWorker.IsBusy) bWorker.RunWorkerAsync(1); } private void btnCancel_Click(object sender, EventArgs e) { if (bWorker.WorkerSupportsCancellation) bWorker.CancelAsync(); }
上面的代碼請(qǐng)注意幾個(gè)地方:
1. 第50行,開(kāi)始調(diào)用RunWorkerAsync方法前,請(qǐng)先判斷IsBusy屬性是否是false,因?yàn)槿绻麨閠rue,則說(shuō)明上一次的調(diào)用還沒(méi)有結(jié)束,再次調(diào)用會(huì)引發(fā)異常。
2. 第56行,調(diào)用CancelAsync方法前,請(qǐng)先設(shè)置WorkerSupportsCancellation屬性為true,否則會(huì)引發(fā)異常。
3. 第26行,調(diào)用ReportProgress方法前,請(qǐng)先設(shè)置WorkerReportsProgress屬性為true,否則會(huì)引發(fā)異常。
4. RunWorkerAsync方法傳遞的參數(shù)是object類(lèi)型,這個(gè)參數(shù)的值可以在DoWork事件的參數(shù)e中的屬性Argument獲得。
5. ReportProgress方法傳遞的參數(shù)可以在事件ProgressChanged中的參數(shù)e中獲得。
6. 調(diào)用CancelAsync方法只是向后臺(tái)的異步線(xiàn)程發(fā)出結(jié)束申請(qǐng),具體什么時(shí)候結(jié)束,由線(xiàn)程自動(dòng)管理。
7. 在RunWorkerCompleted事件中,如果想知道后臺(tái)任務(wù)是正常執(zhí)行完畢還是被調(diào)用CancelAsync方法強(qiáng)制中斷,請(qǐng)參考事件的參數(shù)e的Cancelled屬性。(奇怪的是這個(gè)屬性不會(huì)在你調(diào)用CancelAsync方法后自動(dòng)設(shè)置為true,你需要象代碼中的20行那樣進(jìn)行設(shè)置。)
8. 請(qǐng)注意第7行和第26行的代碼,這兩段代碼中的線(xiàn)程的ID,說(shuō)明了DoWork事件和UI是在兩個(gè)不同的線(xiàn)程上執(zhí)行。
實(shí)際上BackgroundWorker并非直接用來(lái)解決跨線(xiàn)程的控件調(diào)用的問(wèn)題,只是它提供了一種工作機(jī)制,可以讓你的程序利用它來(lái)執(zhí)行異步調(diào)用,并且在異步調(diào)用的過(guò)程中進(jìn)行控件的操作。
關(guān)于.NET跨線(xiàn)程控件的相關(guān)操作是什么問(wèn)題的解答就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,如果你還有很多疑惑沒(méi)有解開(kāi),可以關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道了解更多相關(guān)知識(shí)。