c#之如何安全的跨線程訪問控件

      在窗體開發中用到線程是很常見的事情。好比一邊下載東西一邊點擊其餘功能。若是隻有一個主線程。勢必只會但同一時間處理一個功能,完了以後,纔會去處理下一個功能。這樣的體驗,相比用一次,你就不再想碰了。再好比,加入進度條控件的軟件。進度條從0讀取到100的過程當中,是有一個while循環的。若是你放到主線程裏面執行,那就呵呵了。在這個循環中止前,你會發現你的軟件絕逼處於卡死狀態。鼠標都拖不動它。爲了解決這類問題。咱們須要附加一個線程,至關於請一個助理,幫咱們解決循環的事。這樣咱們的主線程纔有閒工夫管理其餘事。這樣鼠標點擊拖動窗體或者其餘功能就不會受到影響。c#

        好了,讓咱們一塊兒,學習一下,怎麼使用線程,以及附加的自定義線程如何安全的跨線程訪問主線程中的控件。這裏說明一下,全部的控件都屬於主線程的,任何外來線程訪問它,好比給它的屬性賦值操做。都要採起安全的方式訪問。這是軟件開發的原則。那麼如今咱們先來看看,怎麼作,纔是線程訪問不安全的呢?安全

請看代碼:學習

 
 public Form1()
        {
            InitializeComponent();
            Control.CheckForIllegalCrossThreadCalls = false;//禁止編譯器對跨線程訪問作檢查,若是不加這一句,絕逼報錯。不信你試試!
        }
        
private void button1_Click(object sender, EventArgs e)
        {
            Thread thread1 = new Thread(new ParameterizedThreadStart(UpdateLabel));
            thread1.Start("更新Label控件");
        }
        private void UpdateLabel(object str)
        {
            this.label1.Text = str.ToString();//這個線程調用了主線程中的label1控件呵呵
        }

以上就是不安全訪問控件。若是你不加ui

Control.CheckForIllegalCrossThreadCalls = false;

運行是會報錯的。編譯器會對這種跨線程作安全檢查。若是你這樣直接訪問,它是不容許的。因此必須禁用掉才能夠的。固然咯,你禁用掉就能夠正常運行了。可是這樣不安全。作好不要這樣使用咯。平時用的玩不要緊。工做了這樣用,顯得很不專業咯。下面介紹安全的跨線程訪問this

不少網上這樣寫的。發現依然不行。雖然是建立了另一個附加進程,可是它獲取了主線程的控制權,儘管不會報錯,卻是界面會卡死。線程

public partial class Form1 : Form
    {
        private delegate void FlushClient();//代理
        public Form1()
        {
            InitializeComponent();
        }        
        private void Form1_Load(object sender, EventArgs e)
        {
             FlushClient fc=new FlushClient(ThreadFunction); 
             fc.BeginInvoke(null,null);//使用begininvoke方法
        }
         private void ThreadFunction()
        {
              while (true)
            {
                this.textBox1.Text = DateTime.Now.ToString();
                Thread.Sleep(1000);
            }
        }
    }

下面來看看正確的跨線程姿式:代理

第一種方式:code

 delegate void done();
        private Thread thread1 = null;

        private void Form1_Load(object sender, EventArgs e)
        {
            //thread1 = new Thread(new ThreadStart(counter));
            thread1 = new Thread(new ThreadStart(crossthread));
            thread1.IsBackground = true;
            thread1.Start();
        }

        private void crossthread() {
            while (true)
            {
                Thread.Sleep(1000);
                dowork();
            }

        }

        private void dowork() {
            if (this.txt_count.InvokeRequired) {
                done Done = new done(dowork);
                this.Invoke(Done);
            }
            else
            {
                    this.txt_count.Text = DateTime.Now.ToString();
            }
   
        }

近兩天會更新更多的方式。。。暫時寫到這麼多。樓主要睡覺了嘻嘻orm

相關文章
相關標籤/搜索