C#多線程解決界面卡死問題


C#多線程解決界面卡死問題的完美解決方案

文章下最方有源碼下載


   問題描述:
當我們的界面需要在程序運行中不斷更新數據時,

當一個textbox的數據需要變化時,

對於這個問題可以先參考下我的另外一個文章

C#多線程|匿名委托傳參數|測試您的網站能承受的壓力|附源代碼--升級版

為了讓程序執行中不出現界面卡死的現像,最好的方法就是多線程來解決
一個主線程來創建界面,使用一個子線程來執行程序並更新主界面
這樣就不會出現卡死的現像了
這肯定是沒有問題的,
但是為什么在使用的過程中一樣會有很多地方會出現卡死呢,而且有用戶跟我說是我的Httphelper類的問題,其實不是,而且我再次聲明我的Httphelper類跟多線程並沒有關系。不要在誣賴我了哦。
這個問題其實也困或了我很久,但是今天終於解決了,而且我發現很多人有這樣的問題,所以我分享一個例子方便大家參考吧。
先來看看我的界面

當我單擊

開始執行后

是數據在不斷的更新

這個時候界面是不會卡死的,
只是數據在不斷的更新
下面看看我的代碼

復制代碼
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;
using System.Threading;

namespace WindowsFormsApplication3
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        //創建一個委托,是為訪問TextBox控件服務的。
        public delegate void UpdateTxt(string msg);
        //定義一個委托變量
        public UpdateTxt updateTxt;

        //修改TextBox值的方法。
        public void UpdateTxtMethod(string msg)
        {
            richTextBox1.AppendText(msg + "\r\n");
            richTextBox1.ScrollToCaret();
        }

        //此為在非創建線程中的調用方法,其實是使用TextBox的Invoke方法。
        public void ThreadMethodTxt(int n)
        {
            this.BeginInvoke(updateTxt, "線程開始執行,執行" + n + "次,每一秒執行一次");
            for (int i = 0; i < n; i++)
            {
                this.BeginInvoke(updateTxt, i.ToString());
                //一秒 執行一次
                Thread.Sleep(1000);
            }
            this.BeginInvoke(updateTxt, "線程結束");
        }
        //開啟線程
        private void button1_Click(object sender, EventArgs e)
        {
            Thread objThread = new Thread(new ThreadStart(delegate
            {
                ThreadMethodTxt(Convert.ToInt32(textBox1.Text.Trim()));
            }));
            objThread.Start();
        }

        private void Form1_Load_1(object sender, EventArgs e)
        {
            //實例化委托
            updateTxt = new UpdateTxt(UpdateTxtMethod);
        }
    }
}
復制代碼

上面是全部代碼方便大家參考吧

第一步我們先來定義一個委托updateTxt

?
//創建一個委托,是為訪問TextBox控件服務的。
       public  delegate  void  UpdateTxt( string  msg);
       //定義一個委托變量
       public  UpdateTxt updateTxt;

 

主要是使用一個委托來更新界面的richTextBox1

實例方法如下

?
private  void  Form1_Load_1( object  sender, EventArgs e)
       {
           //實例化委托
           updateTxt = new  UpdateTxt(UpdateTxtMethod);
       }

 UpdateTxtMethod方法如下

?
//修改TextBox值的方法。
        public  void  UpdateTxtMethod( string  msg)
        {
            richTextBox1.AppendText(msg + "\r\n" );
            richTextBox1.ScrollToCaret();
        }

 

下面我們來定義一個循環來輸出一個值的,關調用這個委托來更新richTextBox1

?
//此為在非創建線程中的調用方法,其實是使用TextBox的Invoke方法。
        public  void  ThreadMethodTxt( int  n)
        {
            this .BeginInvoke(updateTxt, "線程開始執行,執行"  + n + "次,每一秒執行一次" );
            for  ( int  i = 0; i < n; i++)
            {
                this .BeginInvoke(updateTxt, i.ToString());
                //一秒 執行一次
                Thread.Sleep(1000);
            }
            this .BeginInvoke(updateTxt, "線程結束" );
        }

 然后就是使用一個子線程來調用它了

復制代碼
  //開啟線程
        private void button1_Click(object sender, EventArgs e)
        {
            Thread objThread = new Thread(new ThreadStart(delegate
            {
                ThreadMethodTxt(Convert.ToInt32(textBox1.Text.Trim()));
            }));
            objThread.Start();
        }
復制代碼

 

好了就這樣基本上就可以了。

那問題現在那里呢,其實就出在這一句上

?
this .BeginInvoke(updateTxt, "線程結束" );

 大家也許已經發現了,我是這樣寫的,而不是

?
updateTxt( "線程結束" );

 這樣來直接在子線程中使用,
我相信有很多同志都是這樣寫的,其實錯就錯在這里
如果直接使用

?
updateTxt( "線程結束" );

 大家想一下應該就明白了,
updateTxt是在主線程創建的,而我們在子線程中直接使用,運行的數據多了,就會出現卡死,這是界面信息堵死的原因,
所以就算是委托也不能直接在子線程中使用,而是要使用BeginInvoke方法來調用這個委托
這樣才不會出現卡死的現像。
問題就解決了。
大家支持一下哦
下面是我的源碼提供給大家下載吧   http://files.cnblogs.com/sufei/WindowsFormsApplication3%281%29.zip

 
 


免責聲明!

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



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