委托的前世今生
-Begin-
起因
很多C#初學(xué)者,都遇到過這樣的問題——線程間操作無效,從不是創(chuàng)建控件的線程訪問它。
今天就這個問題,展開分析。

溯源
先說下這個問題產(chǎn)生的根源。
大家都知道,程序運(yùn)行起來之后,首先會有一個主線程,主線程用于處理控件生成、界面渲染、事件響應(yīng)、邏輯處理等操作,因此我們可以理解為窗體里的控件是屬于主線程的。
我們也知道多線程,如果我們想實現(xiàn)與主線程同時執(zhí)行另一件事,一般會去使用多線程。
因此多線程,從某種意義上來說,它和主線程都屬于“線程”這個家族,他們的身份是“平等”的,就像你和你同事之間的關(guān)系一樣。
那么,試想一下,如果你同事有一天想從你手上把你的PLC或者上位機(jī)項目程序拿過去,你愿不愿意?

所以,如果在多線程里操作主線程的控件,你覺得主線程會不會答應(yīng),當(dāng)然不會,主線程不答應(yīng)的最直接表現(xiàn)就是,它會直接給一個報錯,權(quán)當(dāng)警告,如下圖所示:

解決
那么如何解決呢?
你的同事如果非要拿到你的程序,他會想,硬的不行,就來軟的。
所以他會找到你們共同的領(lǐng)導(dǎo),跟你們領(lǐng)導(dǎo)這樣說:“我手頭上的這個100萬的項目,能給公司帶來50%的利潤,現(xiàn)在需要用到他之前那個項目里的一個小知識,需要他把程序給我參考一下”。
在公司利益面前,你覺得你的領(lǐng)導(dǎo)會怎么辦?
于是,領(lǐng)導(dǎo)和你“商量”了一下,毋庸置疑,你妥協(xié)了。
你的同事使用的招數(shù)叫做——委托。
那么,現(xiàn)在回到之前的問題上來,現(xiàn)在多線程要操作主線程的控件,是不是也可以使用委托來實現(xiàn)?
前世
委托定義:委托(Delegate) 是對某個方法的引用的一種引用類型變量。

如果這句話看不懂,那就別看了,跟著我動手做。
1、聲明委托
委托聲明需要根據(jù)執(zhí)行的方法來定,嚴(yán)格來說,就是根據(jù)執(zhí)行方法的返回值和參數(shù),我們只是給窗體的Text設(shè)置一個固定值而已,因此我們的參數(shù)是空,返回值也為空。
聲明委托如下:

2、創(chuàng)建委托對象
委托嚴(yán)格來說是一種類型,就像類一樣,如果想要調(diào)用某個類,必須要創(chuàng)建一個該類的對象,所以我們要創(chuàng)建一個委托對象:

3、創(chuàng)建委托方法
委托對象也只是一個對象而已,就像領(lǐng)導(dǎo)一樣,領(lǐng)導(dǎo)是不可能干活的,最終干活還得靠底下的兵來干,所以我們還得招人去干活。
招人干活就是委托方法,我們現(xiàn)在這個活很簡單,所以我們的方法也很簡單。

4、委托綁定
我們招到了一個“兵”,現(xiàn)在也有一個部門領(lǐng)導(dǎo),怎么把他們聯(lián)系起來呢?
很簡單,讓人事把這個兵分到這個部門就行了,這個分配的過程就是委托綁定,代碼如下:

5、委托調(diào)用
萬事俱備,只欠東風(fēng),終于干活了。
作為公司的老板,一般是不可能跟員工打交道的,他會把任務(wù)分配給部門領(lǐng)導(dǎo),部門領(lǐng)導(dǎo)會把活再分配下去,所以我們委托調(diào)用,也是調(diào)用委托對象。

以上五步,就是委托的實現(xiàn)過程。
然而,我們運(yùn)行之后,還是會報錯。

沒有那么簡單的事!
因為想要在多線程里操作主線程的控件,你還得經(jīng)過控件的同意,怎么經(jīng)過控件同意呢?
控件的父類Control提供了一個這樣的方法:

意思就是說,想要操作控件,必須要通過Invoke方法來實現(xiàn),Invoke方法里參數(shù)是一個委托,于是,我們只能灰溜溜地,這樣寫:

果然,按照規(guī)矩來,就能達(dá)到效果:

今生
微軟從某個版本開始,出來了Action和Lamda表達(dá)式,Action是系統(tǒng)委托,也就是說,不需要我們手動創(chuàng)建委托了,它有個兄弟叫Func,Action沒有返回值,最多可以有16個參數(shù),F(xiàn)unc必須要有返回值,最多可以有16個參數(shù),最后一個參數(shù)表示返回值。
于是我們開始簡化:
第一步簡化:用Action作為委托來創(chuàng)建

第二步簡化:委托對象只用一次,所以可以直接放到參數(shù)里

第三步簡化:用Lamda表達(dá)式代替方法

總結(jié)
我們所以常寫的那行代碼,其實只是一種簡寫方式而已,委托的五步法,不管怎么簡化,怎么優(yōu)化,其實本質(zhì)還是一樣,都離開不了這五個步驟。
這就是經(jīng)典。
都看到這里了,是不是要點個贊呢?

委托的前世今生的評論 (共 條)
