閱讀815 返回首頁    go 阿裏雲 go 技術社區[雲棲]


一個通過BackgroundWorker實現WinForm異步操作的例子

一、場景描述

background._01_01

二、代碼實現

background._01_2

background._01_03

   1: private static int MaxRecords = 100;

   1: private void buttonStartLeft_Click(object sender, EventArgs e)
   2: {
   3:     if (this.backgroundWorkerLeft.IsBusy)
   4:     {
   5:         return;
   6:     }
   7:     this.listBoxLeft.Items.Clear();
   8:     this.backgroundWorkerLeft.RunWorkerAsync(MaxRecords);
   9:     this.buttonStartLeft.Enabled = false;
  10:     this.buttonCacnelLeft.Enabled = true;
  11: } 

   1: private void backgroundWorkerLeft_DoWork(object sender, DoWorkEventArgs e)
   2: {
   3:     try
   4:     {
   5: e.Result = this.RetrieveData(this.backgroundWorkerLeft, e);
   6:     }
   7:     catch (Exception ex)
   8:     {
   9:        MessageBox.Show(ex.Message);
  10:        throw;
  11:     }
  12: } 

   1: private int RetrieveData(BackgroundWorker worker, DoWorkEventArgs e)
   2: {
   3:     int maxRecords = (int)e.Argument;
   4:     int percent = 0;
   5:     for (int i = 1; i <= maxRecords; i++)
   6:     {
   7:         if (worker.CancellationPending)
   8:         {
   9:             return i;
  10:         } 
  11:  
  12:         percent = (int)(((double)i / (double)maxRecords) * 100);
  13:         worker.ReportProgress(percent, new KeyValuePair<int,string>(i,Guid.NewGuid().ToString()));
  14:         Thread.Sleep(100);
  15:     } 
  16:  
  17:     return maxRecords;
  18: } 

   1: private void backgroundWorkerLeft_ProgressChanged(object sender, ProgressChangedEventArgs e)
   2: {
   3:     KeyValuePair<int,string> record = (KeyValuePair<int,string>) e.UserState ;
   4:     this.labelResultLeft.Text = string.Format("There are {0} records retrieved!", record.Key);
   5:     this.progressBarLeft.Value = e.ProgressPercentage;
   6:     this.listBoxLeft.Items.Add(record.Value);
   7: }
注:這些操作需要操作UI上的控件,隻能在Main Thread中進行。如何在RetrieveData方法進行的話,由於該方式是一個異步方法,是會拋出異常的。

   1: private void buttonCacnelLeft_Click(object sender, EventArgs e)
   2: {
   3:     this.backgroundWorkerLeft.CancelAsync();
   4: } 

   1: private void backgroundWorkerLeft_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
   2: {
   3:     try
   4:     {
   5:         this.labelResultLeft.Text = string.Format("Total records: {0}", e.Result);
   6:         this.buttonStartLeft.Enabled = true;
   7:         this.buttonCacnelLeft.Enabled = false;
   8:     }
   9:     catch (TargetInvocationException ex)
  10:     {
  11:         MessageBox.Show(ex.InnerException.GetType().ToString());
  12:     }
  13: }


作者:蔣金楠
微信公眾賬號:大內老A
微博:www.weibo.com/artech
如果你想及時得到個人撰寫文章以及著作的消息推送,或者想看看個人推薦的技術資料,可以掃描左邊二維碼(或者長按識別二維碼)關注個人公眾號(原來公眾帳號蔣金楠的自媒體將會停用)。
本文版權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁麵明顯位置給出原文連接,否則保留追究法律責任的權利。
原文鏈接

最後更新:2017-10-30 17:04:45

  上一篇:go  WCF後續之旅(8):通過WCF Extension 實現與MS Enterprise Library Policy Injection Application Block 的集成
  下一篇:go  WCF後續之旅(9):通過WCF的雙向通信實現Session管理[上篇]