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

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


咨詢
建站咨詢
