程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 更多編程語言 >> 更多關於編程 >> C#多線程界面卡死問題的解決方法

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

編輯:更多關於編程

      問題描述:

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

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

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

      為了讓程序執行中不出現界面卡死的現像,最好的方法就是多線程來解決

      一個主線程來創建界面,使用一個子線程來執行程序並更新主界面

      這樣就不會出現卡死的現像了

      這肯定是沒有問題的,

      但是為什麼在使用的過程中一樣會有很多地方會出現卡死呢,而且有用戶跟我說是我的Httphelper類的問題,其實不是,而且我再次聲明我的Httphelper類跟多線程並沒有關系。不要在誣賴我了哦。

      這個問題其實也困或了我很久,但是今天終於解決了,而且我發現很多人有這樣的問題,所以我分享一個例子方便大家參考吧。先來看看我的界面

    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 + "rn");

      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 + "rn");

      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方法來調用這個委托

      這樣才不會出現卡死的現像。

      問題就解決了。

      大家支持一下哦

    1. 上一頁:
    2. 下一頁:
    Copyright © 程式師世界 All Rights Reserved