新聞中心
.NET 框架是由微軟開(kāi)發(fā)的軟件開(kāi)發(fā)平臺(tái),其最主要的兩個(gè)組成部分是公共語(yǔ)言運(yùn)行時(shí) (CLR) 和框架類(lèi)庫(kù) (FCL),基礎(chǔ)類(lèi)庫(kù) (BCL)是框架類(lèi)庫(kù)的一個(gè)子集,本篇文章重點(diǎn)為大家講解一下.NET多線(xiàn)程。

成都創(chuàng)新互聯(lián)公司主要從事成都做網(wǎng)站、成都網(wǎng)站建設(shè)、網(wǎng)頁(yè)設(shè)計(jì)、企業(yè)做網(wǎng)站、公司建網(wǎng)站等業(yè)務(wù)。立足成都服務(wù)蒙山,10余年網(wǎng)站建設(shè)經(jīng)驗(yàn),價(jià)格優(yōu)惠、服務(wù)專(zhuān)業(yè),歡迎來(lái)電咨詢(xún)建站服務(wù):028-86922220
為什么使用多線(xiàn)程
-
使用戶(hù)界面能夠隨時(shí)相應(yīng)用戶(hù)輸入
當(dāng)某個(gè)應(yīng)用程序在進(jìn)行大量運(yùn)算時(shí)候,為了保證應(yīng)用程序能夠隨時(shí)相應(yīng)客戶(hù)的輸入,這個(gè)時(shí)候我們往往需要讓大量運(yùn)算和相應(yīng)用戶(hù)輸入這兩個(gè)行為在不同的線(xiàn)程中進(jìn)行。
-
效率原因
應(yīng)用程序經(jīng)常需要等待一些資源,如等待網(wǎng)絡(luò)資源,等待io資源,等待用戶(hù)輸入等等。這種情況下使用多線(xiàn)程可以避免CPU長(zhǎng)時(shí)間處于閑置狀態(tài)。
用戶(hù)態(tài),內(nèi)核態(tài)
線(xiàn)程內(nèi)的資源有兩種運(yùn)行態(tài),即用戶(hù)態(tài)和內(nèi)核態(tài)。某些運(yùn)算可以在堆棧上進(jìn)行,這種情況線(xiàn)程是在用戶(hù)態(tài)運(yùn)行的,某些需要高權(quán)限運(yùn)行的指令,或者某些優(yōu)先級(jí)很高的指令需要在操作系統(tǒng)內(nèi)核中進(jìn)行,這個(gè)時(shí)候線(xiàn)程會(huì)運(yùn)行在內(nèi)核態(tài)。出于安全原因,用戶(hù)態(tài)和內(nèi)核態(tài)的資源是不能夠互相訪問(wèn)的,因此在用戶(hù)態(tài)和內(nèi)核態(tài)的切換過(guò)程中,我們需要進(jìn)行相關(guān)上下文以及變量的復(fù)制,這意味的用戶(hù)態(tài)和內(nèi)核態(tài)的切換是以一定的時(shí)間消耗為代價(jià)的。
由于CPU是以時(shí)間片為單位進(jìn)行線(xiàn)程的切換的,由于CPU的運(yùn)算速度遠(yuǎn)大于內(nèi)存的讀寫(xiě)速度,因此CPU和內(nèi)存之間通常有兩級(jí)緩存,不同的線(xiàn)程的上下文訪問(wèn)的數(shù)據(jù)往往是不同的,這樣線(xiàn)程的切換需要經(jīng)常頻繁的切換CPU緩存的內(nèi)容,也需要更新線(xiàn)程的調(diào)度信息,這些都是需要花費(fèi)一定的時(shí)間的,因此合理的使用多線(xiàn)程,來(lái)避免CPU不停的進(jìn)行上下文切換。
System.Thread介紹
創(chuàng)建一個(gè)線(xiàn)程
創(chuàng)建每一個(gè)線(xiàn)程的時(shí)候,CLR都需要進(jìn)行一系列的操作,如初始化線(xiàn)程的本地資源,為線(xiàn)程分配用戶(hù)模式和內(nèi)核模式下相應(yīng)的堆棧,加載相應(yīng)的托管,非托管資源等。
最簡(jiǎn)單常用的創(chuàng)建線(xiàn)程的方式是使用ThreadStart來(lái)創(chuàng)建線(xiàn)程,相關(guān)代碼如下:
ThreadStart只需要一個(gè)委托即可,如果你善于使用匿名方法,也可以用匿名方法來(lái)代替委托,使用匿名方法的另一個(gè)好處是可以通過(guò)匿名方法的閉包特性來(lái)為新的線(xiàn)程傳遞參數(shù)。
雖然使用匿名方法的閉包特性可以很方便的為線(xiàn)程傳遞參數(shù),但是也往往會(huì)帶來(lái)一些不容易發(fā)現(xiàn)的問(wèn)題,如下面的程序,由于i變量的共享,在運(yùn)行的時(shí)候輸出會(huì)有問(wèn)題:
正確的寫(xiě)法應(yīng)該是這樣的:
線(xiàn)程異常的捕獲
如果線(xiàn)程中可能需要捕獲異常,那么我們不能這樣做:
而是這樣做:
System.Thread線(xiàn)程的成員
System.Threading.Thread幫助我們實(shí)現(xiàn)了一些線(xiàn)程的基本操作,如:
| 屬性名稱(chēng) | 說(shuō)明 |
|---|---|
| CurrentContext | 獲取線(xiàn)程正在其中執(zhí)行的當(dāng)前上下文。 |
| CurrentThread | 獲取當(dāng)前正在運(yùn)行的線(xiàn)程。 |
| ExecutionContext | 獲取一個(gè) ExecutionContext 對(duì)象,該對(duì)象包含有關(guān)當(dāng)前線(xiàn)程的各種上下文的信息。 |
| IsAlive | 獲取一個(gè)值,該值指示當(dāng)前線(xiàn)程的執(zhí)行狀態(tài)。 |
| IsBackground | 獲取或設(shè)置一個(gè)值,該值指示某個(gè)線(xiàn)程是否為后臺(tái)線(xiàn)程。 |
| IsThreadPoolThread | 獲取一個(gè)值,該值指示線(xiàn)程是否屬于托管線(xiàn)程池。 |
| ManagedThreadId | 獲取當(dāng)前托管線(xiàn)程的唯一標(biāo)識(shí)符。 |
| Name | 獲取或設(shè)置線(xiàn)程的名稱(chēng)。 |
| Priority | 獲取或設(shè)置一個(gè)值,該值指示線(xiàn)程的調(diào)度優(yōu)先級(jí)。 |
| ThreadState | 獲取一個(gè)值,該值包含當(dāng)前線(xiàn)程的狀態(tài)。 |
顯示詳細(xì)信息
| 方法名稱(chēng) | 說(shuō)明 |
|---|---|
| Abort() | 終止本線(xiàn)程。 |
| GetDomain() | 返回當(dāng)前線(xiàn)程正在其中運(yùn)行的當(dāng)前域。 |
| GetDomainId() | 返回當(dāng)前線(xiàn)程正在其中運(yùn)行的當(dāng)前域Id。 |
| Interrupt() | 中斷處于 WaitSleepJoin 線(xiàn)程狀態(tài)的線(xiàn)程。 |
| Join() | 已重載。阻塞調(diào)用線(xiàn)程,直到某個(gè)線(xiàn)程終止時(shí)為止。 |
| Resume() | 繼續(xù)運(yùn)行已掛起的線(xiàn)程。 |
| Start() | 執(zhí)行本線(xiàn)程。 |
| Suspend() | 掛起當(dāng)前線(xiàn)程,如果當(dāng)前線(xiàn)程已屬于掛起狀態(tài)則此不起作用 |
| Sleep() | 把正在運(yùn)行的線(xiàn)程掛起一段時(shí)間。 |
顯示詳細(xì)信息
前臺(tái)線(xiàn)程vs后臺(tái)線(xiàn)程
這里我們單獨(dú)提一下前臺(tái)線(xiàn)程和后臺(tái)線(xiàn)程。在CLR中,線(xiàn)程分為前臺(tái)線(xiàn)程和后臺(tái)線(xiàn)程,當(dāng)所有前臺(tái)的線(xiàn)程執(zhí)行完之后,CLR會(huì)強(qiáng)制結(jié)束所有正在運(yùn)行的后臺(tái)線(xiàn)程,并且不會(huì)出現(xiàn)任何異常。
因此你應(yīng)該使用前臺(tái)線(xiàn)程來(lái)做一些必須完成的任務(wù),比如把流從內(nèi)存中寫(xiě)到磁盤(pán)上。后臺(tái)線(xiàn)程可以做一些不那么重要的事情。一旦線(xiàn)程對(duì)象的生命周期開(kāi)始,你就不能修改IsBackground值。
由于線(xiàn)程是非常昂貴的資源,我們經(jīng)常需要控制允許多少線(xiàn)程同時(shí)運(yùn)行,如何控制線(xiàn)程的生命周期,如何管理線(xiàn)程,這里我們引入了線(xiàn)程池的概念。
分享標(biāo)題:簡(jiǎn)單講解一下.NET多線(xiàn)程
文章路徑:http://www.5511xx.com/article/codsdgh.html


咨詢(xún)
建站咨詢(xún)
