網(wǎng)站首頁(yè) 編程語(yǔ)言 正文
在我們的程序中,經(jīng)常會(huì)有一些耗時(shí)較長(zhǎng)的運(yùn)算,為了保證用戶體驗(yàn),不引起界面不響應(yīng),我們一般會(huì)采用多線程操作,讓耗時(shí)操作在后臺(tái)完成,完成后再進(jìn)行處理或給出提示,在運(yùn)行中,也會(huì)時(shí)時(shí)去刷新界面上的進(jìn)度條等顯示,必要時(shí)還要控制后臺(tái)線程中斷當(dāng)前操作。
在.net中,提供了一個(gè)組件BackgroundWorker就是專門解決這個(gè)問(wèn)題的。BackgroundWorker類允許在單獨(dú)的專用線程上運(yùn)行操作。 耗時(shí)的操作(如下載和數(shù)據(jù)庫(kù)事務(wù))在長(zhǎng)時(shí)間運(yùn)行時(shí)可能會(huì)導(dǎo)致用戶界面(UI)似乎處于停止響應(yīng)狀態(tài)。如果需要能進(jìn)行響應(yīng)的用戶界面,而且面臨與這類操作相關(guān)的長(zhǎng)時(shí)間延遲,則可以使用BackgroundWorker類方便地解決問(wèn)題。
程序執(zhí)行步驟:
- 1、調(diào)用BackgroundWorker的RunWorkerAsync()方法,如果后臺(tái)操作需要參數(shù),在調(diào)用RunWorkerAsync()方法時(shí)給出參數(shù),在DoWork事件處理程序內(nèi)部,可以從DoWorkEventArgs.Argument屬性中提取該參數(shù)。
- 2、執(zhí)行DoWork事件,后臺(tái)需要執(zhí)行的代碼放到DoWork事件里面執(zhí)行。當(dāng)調(diào)用RunWorkerAsync()方法時(shí),BackgroundWorker通過(guò)觸發(fā)DoWork事件,開(kāi)始執(zhí)行后臺(tái)操作
顯示后臺(tái)操作進(jìn)度:
為了顯示后臺(tái)操作的執(zhí)行進(jìn)度,首先要使WorkerReportsProgress等于true,然后調(diào)用BackgroundWorker的ReportProgress()方法,通過(guò)它傳遞操作完成的進(jìn)度值,此外,該方法觸發(fā)ProgressChanged事件,在此事件中,通過(guò)ProgressChangedEventArgs的實(shí)例,接收到主線程傳遞過(guò)來(lái)的參數(shù)。
取消后臺(tái)操作:
為了使 BackgroundWorker 可以取消后臺(tái)正在執(zhí)行的操作,首先要把屬性WorkerSupportsCancellation 的值設(shè)置為 true。接著調(diào)用CancelAsync()方法,該方法使得屬性CancellationPending 為true,利用CancellationPending 屬性,可以判斷是否取消后臺(tái)異步操作。
后臺(tái)操作完成后,反饋給用戶:
當(dāng)后臺(tái)操作完成以后,無(wú)論是completed 還是cancelled,RunWorkerCompleted()事件都會(huì)被觸發(fā),通過(guò)此方法可以將后臺(tái)操作的完成結(jié)果反饋給用戶。RunWorkerCompleted 事件處理函數(shù)會(huì)在DoWork 事件處理函數(shù)返回后被調(diào)用。通過(guò)它我們可以進(jìn)行一些運(yùn)算結(jié)束后的操作,比如禁用取消按鈕,異常處理,結(jié)果顯示等。注意,如果想要拿到e.Result,您需要在BGWorker_DoWork方法中設(shè)置 e.Result屬性另外,通過(guò)RunWorkerCompletedEventArgs實(shí)例的Cancelled 屬性,以判斷是否是Cancel操作使得后臺(tái)操作終止;
從后臺(tái)操作返回值
在執(zhí)行DoWork事件時(shí)DoWorkEventArgs實(shí)例的Result屬性,返回值到用戶;在RunWorkerCompleted事件里,RunWorkerCompletedEventArgs 實(shí)例的Result屬性接收值;
創(chuàng)建BackgroundWorkerDemo例子:
- 1.新建一個(gè)windows窗體應(yīng)用程序,如:BackgroundWorkerDemo
- 2.拖一個(gè)ProgressBar(進(jìn)度條)和一個(gè)BackgroundWorker控件到Form窗體上,界面如圖:
后臺(tái)代碼:
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using System.IO; using System.Threading; namespace BackgroundWorkerDemo { public partial class FrmDemo : Form { //設(shè)置生成臨時(shí)文件的路徑 static string strSaveDir = @"F:\培訓(xùn)"; public FrmDemo() { InitializeComponent(); //顯示后臺(tái)操作的執(zhí)行進(jìn)度 this.bgWork.WorkerReportsProgress = true; //可以取消后臺(tái)正在執(zhí)行的操作 this.bgWork.WorkerSupportsCancellation = true; } ////// 開(kāi)始 /// /// /// private void btn_Start_Click(object sender, EventArgs e) { if (Directory.Exists(strSaveDir) == false) { return; } btn_Start.Enabled = false; int count = Convert.ToInt32(this.txt_File.Text.ToString().Trim()); //設(shè)置進(jìn)度條 this.proBar.Minimum = 0; this.proBar.Maximum = count; this.proBar.Value = this.proBar.Minimum; //開(kāi)始執(zhí)行異步線程,進(jìn)行后臺(tái)操作,給后臺(tái)傳遞參數(shù) this.bgWork.RunWorkerAsync(count); } ////// 后臺(tái)操作要處理的任務(wù)代碼 /// /// /// private void bgWork_DoWork(object sender, DoWorkEventArgs e) { //獲取從RunWorkerAsync()方法里面?zhèn)鬟f的參數(shù)的值 int fileCount= Convert.ToInt32(e.Argument); Random rand = new Random(); byte[] buffer = new byte[2048]; for (int i = 0; i < fileCount; i++) { try { string strFileName = Path.Combine(strSaveDir, i.ToString() + ".tmp"); using (var stream = File.Create(strFileName)) { int n = 0; int maxByte = 8 * 1024 * 1024; while (n < maxByte) { rand.NextBytes(buffer); stream.Write(buffer, 0, buffer.Length); n += buffer.Length; } } } catch (Exception ex) { continue; } finally { //報(bào)告進(jìn)度 this.bgWork.ReportProgress(i + 1); Thread.Sleep(100); } //判斷是否取消了后臺(tái)操作 if (bgWork.CancellationPending) { e.Cancel = true; return; } //設(shè)置返回值 e.Result = 234; } } ////// 更新前臺(tái)界面進(jìn)度條 /// /// /// private void bgWork_ProgressChanged(object sender, ProgressChangedEventArgs e) { //獲取異步任務(wù)的進(jìn)度百分百 int val = e.ProgressPercentage; this.label2.Text = string.Format("已經(jīng)生成{0}個(gè)文件", val); //進(jìn)度條顯示當(dāng)前進(jìn)度 this.proBar.Value = val; } ////// 后臺(tái)操作完成,向前臺(tái)反饋信息 /// /// /// private void bgWork_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { btn_Start.Enabled = true; //用戶取消操作(e.Cancelled==true,表示異步操作已被取消) if (e.Cancelled) { MessageBox.Show("用戶取消后臺(tái)操作", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information); } else { MessageBox.Show("操作完成", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information); //接收返回值 int result = (int)e.Result; MessageBox.Show("返回值:" + result); } } ////// 取消 /// /// /// private void btn_Cancle_Click(object sender, EventArgs e) { //調(diào)用CancelAsync(),取消掛起的后臺(tái)操作 this.bgWork.CancelAsync(); } } }
運(yùn)行界面:
操作完成界面:
接收返回值:
取消后臺(tái)操作:
原文鏈接:https://www.cnblogs.com/dotnet261010/p/5942034.html
相關(guān)推薦
- 2023-07-07 @RestController 和 @Controller的區(qū)別?
- 2022-07-02 iview中的表格render搭配使用Tooltip 文字提示
- 2022-12-03 C?++迭代器iterator在string中使用方法介紹_C 語(yǔ)言
- 2022-07-11 UVM中設(shè)置打印信息的冗余度閾值和重載打印信息的嚴(yán)重性
- 2022-08-06 詳解Android中motion_toast的使用_Android
- 2022-09-25 Linux基礎(chǔ)組件之基于循環(huán)數(shù)組的無(wú)鎖隊(duì)列
- 2024-04-05 mybatis(mybatis-plus)報(bào)invalid bound statement (not
- 2022-12-19 QT實(shí)現(xiàn)自定義Http客戶端的示例代碼_C 語(yǔ)言
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運(yùn)行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲(chǔ)小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運(yùn)算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過(guò)濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯(cuò)誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實(shí)現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡(jiǎn)單動(dòng)態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對(duì)象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊(duì)列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支