c# BackGroundWorker 多線程操作的小例子


在我們的程序中,經常會有一些耗時較長的運算,為了保證用戶體驗,不引起界面不響應,我們一般會采用多線程操作,讓耗時操作在后台完成,完成后再進行處理或給出提示,在運行中,也會時時去刷新界面上的進度條等顯示元,必要進,還要控制后台線程中斷當前操作。

以前,類似的應用會比較麻煩,需要寫的代碼較多,也很容易出現異常。在 .net中,提供了一個組件 backgroundworker就是專門解決這個問題的。

使用這個組件其實非常簡單,例如,我們做一個類似如下界面的進度條的小例子,在后台線程中進行耗時運算,同時刷新界面上的滾動條和提示信息,運行結束后,彈出處理結果。

c BackGroundWorker 多線程操作的小例子 -  上年紀的程序員  - 有夢就追

在界面上拖入backgroundWorker組件,並響應其三個事件。

代碼如下:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace 多線程小例子
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

//這里就是通過響應消息,來處理界面的顯示工作

        private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            this.progressBar1.Value = e.ProgressPercentage;
            this.label1.Text = e.UserState.ToString();
            this.label1.Update();
        }

//這里是后台工作完成后的消息處理,可以在這里進行后續的處理工作。

        private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            MessageBox.Show("運算終於完成了");
        }

//這里,就是后台進程開始工作時,調用工作函數的地方。你可以把你現有的處理函數寫在這兒。

        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            work(this.backgroundWorker1);
        }

//真正的處理工作

        private bool work(BackgroundWorker bk)
        {
            int tatle =10000;

            for (int i = 0; i < tatle; i++)
            {
                if (bk.CancellationPending) //這里判斷一下是否用戶要求取消后台進行,並可以盡早退出。
                {
                    bk.ReportProgress(i, String.Format("當前值是 {0},操作被用戶申請中斷", i));
                    return false;
                }

//處理的過程中,通過這個函數,向主線程報告處理進度,最好是折算成百分比,與外邊的進度條的最大值必須要對應。這里,我沒有折算,而是把界面線程的進度條最大值調整為與這里的總數一致。
                bk.ReportProgress(i, String.Format("當前值是 {0} ", i));
            }
            return true;
        }

        private void button2_Click(object sender, EventArgs e)
        {

//用戶要求取消時,就這樣處理一下。有時不太靈喔。

                this.backgroundWorker1.CancelAsync();
        }

        private void button1_Click(object sender, EventArgs e)
        {

//這一句,就是讓后台工作開始。

            this.backgroundWorker1.RunWorkerAsync();
        }

        private void button3_Click(object sender, EventArgs e)
        {
            this.Close();
        }
    }
}

 

一般的工作,就這樣的套路處理一下,基本就可以工作了,如果多個線程之間還要交互,或是有共享數據等問題,.net C# 中還是提供 System.Threading.Thread 類,跟傳統用法沒什么大區別,也挺好用的。具體介紹請看另一篇文章。

 
 
 
 
閱讀(42298)評論(21)

 

 
hzsxcn
 
奇山千戶-注冊測繪師
 
botao99284
 
夢幻天使
 
chaoy2010
 
xiafu568
 
shoudongwu
 
lfl-309
 
 
關閉
玩LOFTER,免費沖印20張照片,人人有獎!      我要搶>

評論

  登錄后你可以發表評論,請先登錄。登錄>>
2013-03-04 17:51
程序這樣改就可以運行了: 
public BackGroundWorkerTest()
        {
            InitializeComponent();
            backgroundWorker1.WorkerReportsProgress = true;
            backgroundWorker1.WorkerSupportsCancellation = true;
        }
for (int i = 0; i < tatle; i++)
            {
                if (bk.CancellationPending) // 判斷是否用戶要求取消后台進行,盡早對出
                {
                    bk.ReportProgress(i, String.Format("當前值是 {0},操作被用戶申請中斷", i));
                    return false;
                }
                bk.ReportProgress(i, String.Format("當前值是 {0}", i));
                Thread.Sleep(100); // 加上這一句
            }
private void button_start_Click(object sender, EventArgs e)
        {
            if (this.backgroundWorker1.IsBusy)
                return;
            this.backgroundWorker1.RunWorkerAsync();
        }
2014-03-19 09:47
mandy 回復 Wong
正解
03-17 14:05
ggajj1314  回復 Wong
 Thread.Sleep(100); // 加上這一句
加上這一句后,發現速度明顯慢了不少,正常沒有進度條的速度比有進度條的速度快很多。
2015-11-27 16:58
路過看到的,內容寫的很好,支持~
2015-07-16 19:32
多謝博主,幫我大忙了。
2013-05-30 21:34
隱者

很不錯,別的教程都太難懂,就看到你講的很簡明扼要,把總體的流程講的很清楚。

您肯定是很有經驗的程序員吧?我感覺現在C#的書要不就是邏輯上講的不是很清晰,要不就是講的太簡單,需要的東西很多沒有講到。

很感謝。

2013-01-21 22:20
tjwangzhen
需要做如下設置,程序就可以工作了
backgroundWorker屬性中的事件添加處理函數
WorkerReportsProgress屬性中WorkerReportsProgress設置為true
WorkerReportsProgress屬性中WorkerSupportsCancellation 設置為true     
2012-11-12 14:25
david
有點問題!
2012-10-12 20:57
有課
為什么點完之后界面就假死呢?
2012-09-25 12:31
backgroundWorker,的屬性要修改一下,還有就是進度條的值要修改,取消時會有異常
2012-09-25 12:30
很給力

2012-06-20 16:17
sss

這樣就能用了

除了那個“取消”不能正常使用,其他的都能用

還是很謝謝作者的,我的一個程序很慢,用了他的方法(改寫),一兩秒就跑完了

 

2012-06-20 16:14
sss

大家用的時候要在界面加入下面的東西:

一個 BackgroundWorker 一個lable 一個progressBar 還有三個button

記得 和程序中的名稱 和對應的方法名 一致

2012-06-20 16:11
sss

很好

 

2012-06-02 10:07
9089
沒法用。。。

2012-05-09 18:10
為什么我還有許多錯誤啊
2011-08-05 16:24
11
狗日的。浪費我的時間。什么多線程。界面卡的不行
2010-04-25 12:40
過客

開始按鈕中加個這個合適一些

if (this.backgroundWorker1.IsBusy)
    {
return;
    }

2010-04-25 12:36
過客
多謝老兄!
2009-09-08 14:08
多謝!!學習啦。。。
2009-08-06 16:12
網易博友54
腦殘
 
 
 
 
 
 

網易公司版權所有 ©1997-2016

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM