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

          文章下最方有源碼下載
          問題描述:
          當我們的界面需要在程序運行中不斷更新數據時,當一個textbox的數據需要變化時。
          為了讓程序執行中不出現界面卡死的現像,最好的方法就是多線程來解決,一個主線程來創建界面,使用一個子線程來執行程序并更新主界面,這樣就不會出現卡死的現像了。
          但是為什么在使用的過程中一樣會有很多地方會出現卡死呢?這個問題其實也困或了我很久,但是今天終于解決了,而且我發現很多人有這樣的問題,所以我分享一個例子方便大家參考。
          先來看看我的界面

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

          當我單擊開始執行后

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

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

          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方法來調用這個委托 這樣才不會出現卡死的現像。 問題就解決了。 大家支持一下哦 下面是我的源碼提供給大家下載吧 猛擊下載

          本博客所有文章如無特別注明均為原創

          如果覺得對你有幫助,可以通過下方打賞對作者表示鼓勵

          本文采用知識共享署名-非商業性使用-相同方式共享

          如若轉載,請注明出處:《C#多線程解決界面卡死問題的完美解決方案》http://www.solariosolutions.com/329.html

          (22)
          打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
          鋒哥的頭像鋒哥管理員
          上一篇 2013年6月16日
          下一篇 2013年7月3日

          相關推薦

          發表回復

          登錄后才能評論

          評論列表(3條)

          国产厨房乱子伦露脸,XXXXAAA欧美,日本 888 XXXX,国产欧美日韩一区二区图片