C# 使用委託實現多線程調用窗體的四種方式

一、方法一:使用線程c#

     功能描述:在用c#作WinFrom開發的過程當中。咱們常常須要用到進度條(ProgressBar)用於顯示進度信息。這時候咱們可能就須要用到多線程,若是不採用多線程控制進度條,窗口很容易假死(沒法適時看到進度信息)。下面我就簡單結合一個我寫的例子給你們作一個介紹。多線程

第一步:設計界面,注意須要引用 using System.Threading;函數

實現winfrom進度條及進度信息提示,winfrom程序假死處理 - china_xuhua - 許華
控件名稱分別爲:
progressBar1;label1;textBox1;button1;

第二步:定義一個代理,用於更新ProgressBar的值(Value)及在執行方法的時候,返回方法的處理信息。

        private delegate void SetPos(int ipos,string vinfo);//代理ui

第三步:進度條值更新函數(參數必須跟聲明的代理參數同樣)this

        private void SetTextMesssage(int ipos,string vinfo)
        {
            if (this.InvokeRequired)
            {
                SetPos setpos = new SetPos(SetTextMesssage);
                this.Invoke(setpos, new object[] { ipos,vinfo });
            }
            else
            {
                this.label1.Text = ipos.ToString() + "/1000";
                this.progressBar1.Value = Convert.ToInt32(ipos);
                this.textBox1.AppendText(vinfo);
            }
        }線程

第四步:函數實現設計

        private void button1_Click(object sender, EventArgs e)
        {
            Thread fThread = new Thread(new ThreadStart(SleepT));
            fThread.Start();
        }代理

第五步:新的線程執行函數:orm

        private void SleepT()
        {
            for (int i = 0; i < 500; i++)
            {
                System.Threading.Thread.Sleep(10);
                SetTextMesssage(100*i/500,i.ToString()+"\r\n");
            }
        }事件

程序運行效果圖:

實現winfrom進度條及進度信息提示,winfrom程序假死處理 - china_xuhua - 許華
 
=========================================================================================
二、第二種方法:
     功能描述:該種方法經過控件backgroundWorker1實現,進度條。卻進度條在一個模板窗體內。
 
第一步:主窗體設計:
實現winfrom進度條及進度信息提示,winfrom程序假死處理 - china_xuhua - 許華 

 控件名稱:

button1;backgroundWorker1;

對backgroundWorker1控件,屬性設置:

實現winfrom進度條及進度信息提示,winfrom程序假死處理 - china_xuhua - 許華
 

 第二步:主頁面後臺代碼:

using System.Threading;//引用空間名稱

        private void button1_Click(object sender, EventArgs e)
        {
            this.backgroundWorker1.RunWorkerAsync(); // 運行 backgroundWorker 組件

            ProcessForm form = new ProcessForm(this.backgroundWorker1);// 顯示進度條窗體 
            form.ShowDialog(this);
            form.Close();
        }

        private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if (e.Error != null)
            {
                MessageBox.Show(e.Error.Message);
            }
            else if (e.Cancelled)
            {
            }
            else
            {
            }
        }
        //你能夠在這個方法內,實現你的調用,方法等。
        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            BackgroundWorker worker = sender as BackgroundWorker;
            for (int i = 0; i < 100; i++)
            {
                Thread.Sleep(100);
                worker.ReportProgress(i);
                if (worker.CancellationPending)  // 若是用戶取消則跳出處理數據代碼 
                {
                    e.Cancel = true;
                    break;
                }
            }
        }
分別爲button控件和backgroundWorker1控件選好事件。

第三步:設置子窗體(及顯示進度條的窗體):

實現winfrom進度條及進度信息提示,winfrom程序假死處理 - china_xuhua - 許華
控件名稱:
progressBar1;button1
 
第四步:子窗體,後臺代碼:

         private BackgroundWorker backgroundWorker1; //ProcessForm 窗體事件(進度條窗體)

        public ProcessForm(BackgroundWorker backgroundWorker1)
        {
            InitializeComponent();

            this.backgroundWorker1 = backgroundWorker1;
            this.backgroundWorker1.ProgressChanged += new ProgressChangedEventHandler(backgroundWorker1_ProgressChanged);
            this.backgroundWorker1.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backgroundWorker1_RunWorkerCompleted);
        }

        void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            //this.Close();//執行完以後,直接關閉頁面
        }

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

        private void button1_Click(object sender, EventArgs e)
        {
            this.backgroundWorker1.CancelAsync();
            this.button1.Enabled = false;
            this.Close();
        }
    }

只爲button選好事件
 

執行效果爲:

實現winfrom進度條及進度信息提示,winfrom程序假死處理 - china_xuhua - 許華

 =================================================================================================

三、第三種方法:

     功能描述:在處理大量數據的時候,有時候方法的執行須要必定的時間,這時候每每會形成頁面或程序的「假死」狀態,給用戶的體驗度也不是很好。爲了不出現「假死」提升用戶的體驗度,在這裏爲這類型的方法加了一個進度條和一個文本框,進度條用於顯示程序處理的進度,文本框用於顯示在處理過程當中,給與的提示。本方法主要使用了控件:backgroundWorker1;說明:本方法與上面的方法(方法二)基本類型,主要是設計和代碼進行了一些修改。


 第一步:主窗體設計:
實現winfrom進度條及進度信息提示,winfrom程序假死處理 - china_xuhua - 許華 

控件名稱:

button1;backgroundWorker1;

對backgroundWorker1控件,屬性設置:


實現winfrom進度條及進度信息提示,winfrom程序假死處理 - china_xuhua - 許華

第二步:主窗體 後臺代碼:

        private void button1_Click(object sender, EventArgs e)
        {
            this.backgroundWorker1.RunWorkerAsync(); // 運行 backgroundWorker 組件

            ProcessForm form = new ProcessForm(this.backgroundWorker1);// 顯示進度條窗體 
            form.ShowDialog(this);
            form.Close();
        }

        private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if (e.Error != null)
            {
                MessageBox.Show(e.Error.Message);
            }
            else if (e.Cancelled)
            {
            }
            else
            {
            }
        }
        //你能夠在這個方法內,實現你的調用,方法等。
        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            BackgroundWorker worker = sender as BackgroundWorker;
            for (int i = 0; i < 100; i++)
            {
                Thread.Sleep(100);
                worker.ReportProgress(i, i.ToString() + "  你好!\r\n"); //注意:這裏向子窗體返回信息值,這裏是兩個值,一個用於進度條,一個用於文本框的。
                if (worker.CancellationPending)  // 若是用戶取消則跳出處理數據代碼 
                {
                    e.Cancel = true;
                    break;
                }
            }
        }

第三步:設置子窗體(及顯示進度條的窗體):

實現winfrom進度條及進度信息提示,winfrom程序假死處理 - china_xuhua - 許華

 控件:

progressBar1;textBox1;button1

第四步:子窗體後臺代碼:

        private BackgroundWorker backgroundWorker1; //ProcessForm 窗體事件(進度條窗體)

        public ProcessForm(BackgroundWorker backgroundWorker1)
        {
            InitializeComponent();

            this.backgroundWorker1 = backgroundWorker1;
            this.backgroundWorker1.ProgressChanged += new ProgressChangedEventHandler(backgroundWorker1_ProgressChanged);
            this.backgroundWorker1.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backgroundWorker1_RunWorkerCompleted);
        }

        void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            //this.Close();//執行完以後,直接關閉頁面
        }

        void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            this.progressBar1.Value = e.ProgressPercentage;
            this.textBox1.AppendText(e.UserState.ToString());//主窗體傳過來的值,經過e.UserState.ToString()來接受
        }

        private void button1_Click(object sender, EventArgs e)
        {
            this.backgroundWorker1.CancelAsync();
            this.button1.Enabled = false;
            this.Close();
        }

實現的效果:

實現winfrom進度條及進度信息提示,winfrom程序假死處理 - china_xuhua - 許華
注意:若是在程序爲執行完,就點擊取消的話,頗有可能會報錯的,這時候,你就修改一個方法:backgroundWorker1_ProgressChanged
以下:
        void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            this.progressBar1.Value = e.ProgressPercentage;
            this.textBox1.Text += e.UserState.ToString(); //主窗體傳過來的值,經過e.UserState.ToString()來接受
        }
       把這個方法,替換上邊的那個方法,就能夠了。
=====================================================================================================
四、第四種方法:
     功能描述:本方法實現進度條顯示,方法執行信息反饋顯示。用到的技術點爲 線程與代理。
     
    步驟一:添加主頁面。
      
實現winfrom進度條及進度信息提示,winfrom程序假死處理 - china_xuhua - 許華
 
控件名稱:
button1;
 
  步驟二:主頁面後臺代碼
        using System.Threading;//引用此命名
 
        //建立代理。
        private Form6 myProcessBar = null;//彈出的子窗體(用於顯示進度條)
        private delegate bool IncreaseHandle(int nValue,string vinfo);//代理建立
        private IncreaseHandle myIncrease = null;//聲明代理,用於後面的實例化代理
        private int vMax = 100;//用於實例化進度條,能夠根據本身的須要,本身改變
 
        private void button1_Click(object sender, EventArgs e)
        {
            Thread thdSub = new Thread(new ThreadStart(ThreadFun));
            thdSub.Start();
        }
        private void ThreadFun()
        {
            MethodInvoker mi = new MethodInvoker(ShowProcessBar);
            this.BeginInvoke(mi);
            Thread.Sleep(100);
            object objReturn = null;
            for (int i = 0; i < vMax; i++)
            {
                objReturn = this.Invoke(this.myIncrease, new object[] { 2, i.ToString() + "\r\n" });
                Thread.Sleep(50);
            }
        }
        private void ShowProcessBar()
        {
            myProcessBar = new Form6(vMax);
            myIncrease = new IncreaseHandle(myProcessBar.Increase);
            myProcessBar.ShowDialog();
            myProcessBar = null;
        }
 
步驟三:建立子窗體
實現winfrom進度條及進度信息提示,winfrom程序假死處理 - china_xuhua - 許華
 控件名稱:
progressBar1;textBox1
 
步驟四:子窗體,後臺代碼
        public Form6(int vMax)
        {
            InitializeComponent();
            this.progressBar1.Maximum = vMax;
        }
        public bool Increase(int nValue,string nInfo)
        {
            if (nValue > 0)
            {
                if (progressBar1.Value + nValue < progressBar1.Maximum)
                {
                    progressBar1.Value += nValue;
                    this.textBox1.AppendText(nInfo);
                    Application.DoEvents();
                    progressBar1.Update();
                    progressBar1.Refresh();
                    this.textBox1.Update();
                    this.textBox1.Refresh();
                    return true;
                }
                else
                {
                    progressBar1.Value = progressBar1.Maximum;
                    this.textBox1.AppendText(nInfo);
                    //this.Close();//執行完以後,自動關閉子窗體
                    return false;
                }
            }
            return false;
        }
 
執行效果:
實現winfrom進度條及進度信息提示,winfrom程序假死處理 - china_xuhua - 許華
 
相關文章
相關標籤/搜索