在多線程中處理界面的響應信息,確實沒有單線程那麼容易,直接賦值就OK了,必須得通過委託到主線程中才可以處理,這個小DEMO實現了兩個線程同時在主界面上進行輸入.當初自己怎麼也弄不明白這些道理,只要弄出第一個實例,後面的就輕鬆多了,萬事入門難嘛.直接貼代碼,解釋都在註釋裏了,其他就不多廢話了.
- private void button1_Click(object sender, EventArgs e)
- {
- //初學的時候這裏經常弄不清楚到底是該用ThreadStart還是用Thread
- //其實沒有必要一定要弄到ThreadStart的,它只是使用委託線程
- //Thread t = new Thread (new ThreadStart (Go));相當於下面的寫法:
- //public delegate void ThreadStart();
- //Thread t = new Thread (new ThreadStart (Go));編譯的時候將和委託一樣
- //Thread t = new Thread (delegate() { Go中的代碼 });
- Thread s1 = new Thread(addwebper1s);
- //IsBackground是申明一個後臺線程,爲什麼做後臺線程呢?
- //因爲主線程退出的時候,後臺線程會自動銷燬,否則回駐留在內存中
- s1.IsBackground = true;
- s1.Start();
- Thread s2 = new Thread(addwebper2s);
- s2.IsBackground = true;
- s2.Start();
- }
- private void addwebper2s()
- {
- while (true)
- {
- AddMsg("http://www.csdn.net/r/n");
- //線程休眠2秒
- Thread.Sleep(2 * 1000);
- }
- }
- private void addwebper1s()
- {
- while (true)
- {
- AddMsg("http://blog.csdn.net/much0726/r/n");
- //線程休眠1秒
- Thread.Sleep(1 * 1000);
- }
- }
- delegate void addmsg(string msg);
- private void AddMsg(string msg)
- {
- //把鼠標放上去看解釋就知道了,就是防止創建控件以外的線程調用(.NET是類型安全的)
- if (this.InvokeRequired)
- {
- //爲當前控件指定委託
- this.Invoke(new addmsg(AddMsg), msg);
- }
- else
- {
- //被委託到主線程後真正執行的代碼
- //爲什麼會執行到這裏?
- //不好解釋,大概是因爲委託的主線程後,this.InvokeRequired=false了吧
- textBox1.Text += msg;
- }
- }
小結
雖然在多線中訪問主線中的控件資源,表象看來,好象必須要對改控件進行互斥鎖,但是,實際上是沒有必要的,這點我也沒有弄明白爲什麼,在多線程中,複雜的界面響應也會給程序帶來更多的BUG,測試成本會無形的擴大,個人建議,如果是服務端程序就使用控制太的Console輸出就可以了,如果是用戶體驗要求比較高的程序,需要進行多方面的壓力測試纔行.