日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

基于事件的异步模式——BackgroundWorker

發布時間:2024/1/17 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 基于事件的异步模式——BackgroundWorker 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

轉自strangeman原文 基于事件的異步模式——BackgroundWorker

?

  實現異步處理的方法很多,經常用的有基于委托的方式,今天記錄的是基于事件的異步模式。利用BackgroundWorker組件可以很輕松的實現異步處理,并且該組件還支持事件的取消、進度報告等功能。本文以計算兩個數X、Y的和為例。

  通過反編譯可以看到,這個組件內部也是通過異步委托實現的,報告進度、取消事件等運用了事件技術實現,而事件的本質其實就是委托。

程序界面如下圖,其中三個文本框分別為兩個加數和處理結果,兩個按鈕為計算和取消,按鈕下方為進度條。

引入BackgroundWorker組件,為DoWork、ProgressChanged、RunWorkerCompleted三個事件指定方法。
WorkerReportsProgress屬性設為true,以支持報告進度。
WorkerSupportsCancellation屬性設置為true,以支持取消。

public MainForm() {InitializeComponent();this.backgroundWorker1.DoWork += this.BackgroundWorker1DoWork;this.backgroundWorker1.ProgressChanged += this.BackgroundWorker1ProgressChanged;this.backgroundWorker1.RunWorkerCompleted += this.BackgroundWorker1RunWorkerCompleted;this.backgroundWorker1.WorkerReportsProgress = true;this.backgroundWorker1.WorkerSupportsCancellation = true;this.buttonCancel.Enabled = false; }

?

?

?

3. 當點擊計算按鈕時,調用BackgroundWorkerRunWorkerAsync方法實現異步處理,該方法支持一個object類型的參數。這里用元組Tuple<int,int>傳遞X、Y的值。調用RunWorkerAsync方法,將觸發DoWork事件。

this.backgroundWorker1.RunWorkerAsync(new Tuple<int,int>(Convert.ToInt32(this.textBoxX.Text), Convert.ToInt32(this.textBoxY.Text)));

?通過反編譯看到以下實現代碼:

?

public void RunWorkerAsync(object argument) {if (this.isRunning){throw new InvalidOperationException(SR.GetString("BackgroundWorker_WorkerAlreadyRunning"));}this.isRunning = true;this.cancellationPending = false;this.asyncOperation = AsyncOperationManager.CreateOperation(null);this.threadStart.BeginInvoke(argument, null, null);}

?

可以看到其內部也是通過異步委托實現的,其中threadStart的定義:private?delegate?void?WorkerThreadStartDelegate(object?argument);就是一個委托類型。

?

4. 當點擊取消按鈕時,調用BackgroundWorkerCancelAsync方法,這將改變BackgroundWorkerCancellationPending屬性的值為ture。當執行OnWork方法時可以根據CancellationPending屬性,判斷用戶是否要取消事件。

this.backgroundWorker1.CancelAsync();??

?再看看其內部:

public void CancelAsync() {if (!this.WorkerSupportsCancellation){throw new InvalidOperationException(SR.GetString("BackgroundWorker_WorkerDoesntSupportCancellation"));}this.cancellationPending = true; }

?

如上面所說,改變只讀屬性CancellationPending的值為ture。

5. 這里在DoWork方法中
根據CancellationPending屬性,判斷是否取消。若取消,應在方法結束之前將DoWorkEventArgsCancel屬性設置為ture。這將用于RunWorkerCompleted事件中判斷事件取消還是正常完成。
通過ReportProgress方法報告進度, 調用該方法時傳遞了一個int類型的參數,該方法將觸發ProgressChanged事件。

void BackgroundWorker1DoWork(object sender, System.ComponentModel.DoWorkEventArgs e) {for (int i = 0; i < 10; i++) {System.Threading.Thread.Sleep(500);//模擬耗時操作if (backgroundWorker1.CancellationPending) {e.Cancel = truereturn; } else {backgroundWorker1.ReportProgress(i * 10); }}var t = e.Argument as Tuple<int,int>;e.Result = t.Item1 + t.Item2; }

?

?

?再看報告進度是怎么基于事件實現的:

?

1.我們調用的ReportProgress方法public void ReportProgress(int percentProgress) {this.ReportProgress(percentProgress, null); }2.ReportProgress另一個重載,可以帶一個自定義參數,方便傳遞其他內容,例如一般安裝程序中的“正在復制文件”,“正在注冊相關組件”提示信息等。public void ReportProgress(int percentProgress, object userState) {if (!this.WorkerReportsProgress){throw new InvalidOperationException(SR.GetString("BackgroundWorker_WorkerDoesntReportProgress"));}ProgressChangedEventArgs progressChangedEventArgs = new ProgressChangedEventArgs(percentProgress, userState);if (this.asyncOperation != null){this.asyncOperation.Post(this.progressReporter, progressChangedEventArgs);return;}this.progressReporter(progressChangedEventArgs);}

?

3.觸發事件

private void ProgressReporter(object arg) {this.OnProgressChanged((ProgressChangedEventArgs)arg); }

?

6. ProgressChanged事件,會將控制權交給UI線程。在其實現方法中根據ProgressChangedEventArgsProgressPercentage屬性獲取進度值。

void BackgroundWorker1ProgressChanged(object sender, System.ComponentModel.ProgressChangedEventArgs e) {this.progressBar1.Value = e.ProgressPercentage; }

?

7. OnWork退出后,將調用RunWorkerCompleted事件。
根據RunWorkerCompletedEventArgsCancelled屬性判斷是否正常完成。
根據RunWorkerCompletedEventArgsResult屬性獲取處理結果。

void BackgroundWorker1RunWorkerCompleted(object sender, System.ComponentModel.RunWorkerCompletedEventArgs e){this.textBoxResult.Text = e.Cancelled ? "Canceled" : e.Result.ToString();this.buttonCancel.Enabled = false;this.buttonCalculate.Enabled = true;this.progressBar1.Value = 100;}

?

?

?

8. 完整代碼

/** 由SharpDevelop創建。* 用戶: David Huang* 日期: 2015/9/8* 時間: 14:54*/ using System; using System.Windows.Forms;namespace BackgroundWorkerTest {/// <summary>/// Description of MainForm./// </summary>public partial class MainForm : Form{public MainForm(){InitializeComponent();this.backgroundWorker1.DoWork += this.BackgroundWorker1DoWork;this.backgroundWorker1.ProgressChanged += this.BackgroundWorker1ProgressChanged;this.backgroundWorker1.RunWorkerCompleted += this.BackgroundWorker1RunWorkerCompleted;this.backgroundWorker1.WorkerReportsProgress = true;this.backgroundWorker1.WorkerSupportsCancellation = true;this.buttonCancel.Enabled = false;}void ButtonCalculateClick(object sender, EventArgs e){this.buttonCalculate.Enabled = false;this.textBoxResult.Text = string.Empty;this.buttonCancel.Enabled = true;this.backgroundWorker1.RunWorkerAsync(new Tuple<int,int>(Convert.ToInt32(this.textBoxX.Text), Convert.ToInt32(this.textBoxY.Text))); }void ButtonCancelClick(object sender, EventArgs e){this.backgroundWorker1.CancelAsync(); }void BackgroundWorker1DoWork(object sender, System.ComponentModel.DoWorkEventArgs e){for (int i = 0; i < 10; i++) {System.Threading.Thread.Sleep(500); if (backgroundWorker1.CancellationPending) {e.Cancel = true;return;} else {backgroundWorker1.ReportProgress(i * 10);}}var t = e.Argument as Tuple<int,int>;e.Result = t.Item1 + t.Item2;}void BackgroundWorker1ProgressChanged(object sender, System.ComponentModel.ProgressChangedEventArgs e){this.progressBar1.Value = e.ProgressPercentage;}void BackgroundWorker1RunWorkerCompleted(object sender, System.ComponentModel.RunWorkerCompletedEventArgs e){this.textBoxResult.Text = e.Cancelled ? "Canceled" : e.Result.ToString();this.buttonCancel.Enabled = false;this.buttonCalculate.Enabled = true;this.progressBar1.Value = 100;}} } View Code

?


代碼下載:點我

?

?

總結

以上是生活随笔為你收集整理的基于事件的异步模式——BackgroundWorker的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。