C#利用委託跨線程更新UI資料

來源:互聯網
上載者:User

         在使用C#的過程中,難免會用到多線程,而用多線程之後,線程如何與介面互動則是一個非常頭疼的問題。其實不僅僅是介面,一般情況下,我們往往需要獲得線程的一些資訊來確定線程的狀態。比較好的方式是用委託實現,看例子:

         註:本例利用委託和跨線程訪問技術,用介面上的兩個label控制項即時顯示線程的執行次數。網上雖然有很多這方面的文章,但是過於簡略,說明很少,剛剛接觸這方面的程式員很難理解,故寫此文。

 

TestClass類:

 

class TestClass{        //聲明一個delegate(委託)類型:testDelegate,該類型可以搭載傳回值為空白,參數只有一個(long型)的方法。        public delegate void testDelegate(long i);        //聲明一個testDelegate類型的對象。該對象代表了傳回值為空白,參數只有一個(long型)的方法。它可以搭載N個方法。        public testDelegate mainThread;        /// <summary>        /// 測試方法        /// </summary>        public void testFunction()         {            long i = 0;            while(true)            {                i++;                mainThread(i); //調用委派物件                Thread.Sleep(1000);  //線程等待1000毫秒            }        }}

 

winform介面代碼:

 

/// <summary>/// 按鈕單擊事件/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void button1_Click(object sender, EventArgs e){    //建立TestClass類的對象    TestClass testclass = new TestClass();    //在testclass對象的mainThread(委託)對象上搭載兩個方法,線上程中調用mainThread對象時相當於調用了這兩個方法。    testclass.mainThread = new TestClass.testDelegate(refreshLabMessage1);    testclass.mainThread += new TestClass.testDelegate(refreshLabMessage2);    //建立一個無參數的線程,這個線程執行TestClass類中的testFunction方法。    Thread testclassThread = new Thread(new ThreadStart(testclass.testFunction));    //啟動線程,啟動之後線程才開始執行    testclassThread.Start();}/// <summary>/// 在介面上更新線程執行次數/// </summary>/// <param name="i"></param>private void refreshLabMessage1(long i) {    //判斷該方法是否被主線程調用,也就是建立labMessage1控制項的線程,當控制項的InvokeRequired屬性為ture時,說明是被主線程以外的線程調用。如果不加判斷,會造成異常    if (this.labMessage1.InvokeRequired)    {        //再次建立一個TestClass類的對象        TestClass testclass = new TestClass();        //為新對象的mainThread對象搭載方法        testclass.mainThread = new TestClass.testDelegate(refreshLabMessage1);        //this指表單,在這調用表單的Invoke方法,也就是用表單的建立線程來執行mainThread對象委託的方法,再加上需要的參數(i)        this.Invoke(testclass.mainThread,new object[] {i});    }    else    {        labMessage1.Text = i.ToString();    }}/// <summary>/// 在介面上更新線程執行次數/// </summary>/// <param name="i"></param>private void refreshLabMessage2(long i){    //同上    if (this.labMessage2.InvokeRequired)    {        //再次建立一個TestClass類的對象        TestClass testclass = new TestClass();        //為新對象的mainThread對象搭載方法        testclass.mainThread = new TestClass.testDelegate(refreshLabMessage2);        //this指表單,在這調用表單的Invoke方法,也就是用表單的建立線程來執行mainThread對象委託的方法,再加上需要的參數(i)        this.Invoke(testclass.mainThread, new object[] { i });    }    else    {        labMessage2.Text = i.ToString();    }}

 

 

執行效果:


 

說明:

 

 

為了便於大家理解,我寫了很詳細的注釋。在這還要說明一下,因為這裡邊有些“莫名其妙”的地方。


l  如何建立線程就不廢話了,一看就懂。


l  public delegate void testDelegate(long i);這句話是建立了一個委託,名字是testDelegate,指定了委託的類型,什麼傳回值啦、什麼參數啦,可以把testDelegate理解為一個類,一個規範;publictestDelegate mainThread;這句話當然就是建立testDelegate類的對象了,真正搭載方法的是mainThread對象,它可以搭載N個方法,順序執行。如何搭載捏?看這句話:testclass.mainThread=
new TestClass.testDelegate(refreshLabMessage1);這句話是給testclass對象中的mainThread對象搭載方法,但是後邊的new比較難以理解。大家都知道,new這個關鍵字就是用來建立對象的,剛剛已經提醒大家把委託看成一個類,因此這new的是testDelegate這個委託,而不是TestClass(一定要看清了,如果是new的TestClass,要在TestClass後加括弧的,後邊接的是方法,而testDelegate明顯不是方法,因此會報錯)。相當於是在TestClass類中又套了一個類,所以才會這樣寫。refreshLabMessage1當然就是testDelegate類構造方法的參數,用來指明委託哪個方法。最後把執行個體賦給同類型的mainThread。另外,在此例中mainThread委託了兩個方法,用+=運算子即可,如果想去除某個方法,亦可用-=運算子。


l  最後需要說明的就是跨線程訪問控制項問題。表單上的控制項只允許建立它們的線程訪問,也就是主線程,如果非主線程訪問則會發生異常。我們可以藉助於控制項的InvokeRequired屬性來判斷該控制項目前是否被主線程訪問,如果是,返回false。如果不是,再利用Invoke方法找到主線程,讓主線程執行訪問控制項的方法,本例中藉助於TestClass類中的mainThread對象,委託了訪問控制項的方法refreshLabMessage1,再把mainThread對象傳入運行在主線程上的控制項的Invoke方法即可。Invoke方法可以理解為:在哪個控制項上調用了Invoke,就用那個控制項所在的線程處理委託方法。在本例中用this調用Invoke方法,也就是表單所在的線程,當然也是控制項所在的線程。Invoke的兩個參數分別是:委託、委託的方法需要的參數。

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.