



下載本文檔
版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
1、一 Thread 類庫Windows 是一個(gè)多任務(wù)的系統(tǒng),如果你使用的是windows 2000及其以上版本,你可以通過任務(wù)管理器查看當(dāng)前系統(tǒng)運(yùn)行的程序和進(jìn)程。什么是進(jìn)程呢?當(dāng)一個(gè)程序開始運(yùn)行時(shí),它就是一個(gè)進(jìn)程, 進(jìn)程所指包括運(yùn)行中的程序和程序所使用到的內(nèi)存和系統(tǒng)資源。而一個(gè)進(jìn)程又是由多個(gè)線程所組成的,線程是程序中的一個(gè)執(zhí)行流,每個(gè)線程都有自己的專有寄存器( 棧指針、程序計(jì)數(shù)器等) ,但代碼區(qū)是共享的,即不同的線程可以執(zhí)行同樣的函數(shù)。多線程是指程序中包含多個(gè)執(zhí)行流,即在一個(gè)程序中可以同時(shí)運(yùn)行多個(gè)不同的線程來執(zhí)行不同的任務(wù),也就是說允許單個(gè)程序創(chuàng)建多個(gè)并行執(zhí)行的線程來完成各自的任務(wù)。一 關(guān)于 T
2、hread 的說明在 framework class library 中,所有與多線程機(jī)制應(yīng)用相關(guān)的類都是放在命名空間中的。其中提供 Thread 類用于創(chuàng)建線程, ThreadPool 類用于管理線程池等等,此外還提供解決了線程執(zhí)行安排, 死鎖,線程間通訊等實(shí)際問題的機(jī)制。 如果你想在你的應(yīng)用程序中使用多線程,就必須包含這個(gè)類。 Thread 類有幾個(gè)至關(guān)重要的方法,描述如下:Start():啟動(dòng)線程Sleep(int):靜態(tài)方法,暫停當(dāng)前線程指定的毫秒數(shù)Abort():通常使用該方法來終止一個(gè)線程Suspend() :該方法并不終止未完成的線程,它僅僅掛起線程,以后還可恢復(fù)。Resume(
3、) :恢復(fù)被Suspend() 方法掛起的線程的執(zhí)行線程入口使程序知道該讓這個(gè)線程干什么事,在(delegate )來提供的, 你可以把 ThreadStart數(shù),當(dāng)調(diào)用()方法后,線程就開始執(zhí)行C#中,線程入口是通過ThreadStart代理理解為一個(gè)函數(shù)指針,指向線程要執(zhí)行的函ThreadStart所代表或者說指向的函數(shù)。ThreadState在各種情況下的可能取值如下:Aborted :線程已停止AbortRequested :線程的 () 方法已被調(diào)用,但是線程還未停止Background :線程在后臺(tái)執(zhí)行,與屬性有關(guān)Running :線程正在正常運(yùn)行Stopped :線程已經(jīng)被停止S
4、topRequested :線程正在被要求停止Suspended:線程已經(jīng)被掛起(此狀態(tài)下,可以通過調(diào)用Resume()方法重新運(yùn)行)SuspendRequested :線程正在要求被掛起,但是未來得及響應(yīng)Unstarted :未調(diào)用 () 開始線程的運(yùn)行WaitSleepJoin:線程因?yàn)檎{(diào)用了Wait(),Sleep()或 Join()等方法處于封鎖狀態(tài)二 Winform 中使用的 thread首先可以看看最直接的方法, 也是 下支持的方法。 但請注意的是, 此方法在 以后就已經(jīng)是一種錯(cuò)誤的方法了。csharp view plain copy在 CODE上查看代碼片派生到我的代碼片publ
5、ic partial class Form1 : Formpublic Form1()InitializeComponent();private void Form1_Load(object sender, EventArgs e)Thread thread = new Thread(ThreadFuntion);= true;();private void ThreadFuntion()while (true)=(1000);這段 code 在 vs2005 或者 2008 上都拋出異常:Cross-threadoperationnot valid:ControltextBox1 acces
6、sed from a thread other than the thread it was created on .這是因?yàn)橐院蠹訌?qiáng)了安全機(jī)制,不允許在winform 中直接跨線程訪問控件的屬性。那么怎么解決這個(gè)問題呢,下面提供幾種方案。第一種方案: 在 Thread 創(chuàng)建之氣, 將 設(shè)為 false 。 此代碼告訴編譯器:在這個(gè)類中我們不檢查跨線程的調(diào)用是否合法 (如果沒有加這句話運(yùn)行也沒有異常, 那么說明系統(tǒng)以及默認(rèn)的采用了不檢查的方式)。然而,這種方法不可取。我們查看CheckForIllegalCrossThreadCalls 這個(gè)屬性的定義,就會(huì)發(fā)現(xiàn)它是一個(gè) static 的,也就
7、是說無論我們在項(xiàng)目的什么地方修改了這個(gè)值, 他就會(huì)在全局起作用。 而且像這種跨線程訪問是否存在異常, 我們通常都會(huì)去檢查。 如果項(xiàng)目中其他人修改了這個(gè)屬性, 那么我們的方案就失敗了,我們要采取另外的方案。第二種方案csharp view plain copy在 CODE上查看代碼片派生到我的代碼片namespace TestInvokerpublic partial class Form1 : Formpublic Form1()InitializeComponent();private void button1_Click(object sender, EventArgs e)Threadt
8、hread=newThread(newThreadStart(StartSomeWorkFromUIThread);= true;();et框架上似乎沒有發(fā)現(xiàn)問題,但是這根本就是錯(cuò)的,更糟糕的是,程序員在這里不會(huì)得到任何錯(cuò)誤提示,一開始就上當(dāng)受騙,之后會(huì)莫明其妙地發(fā)現(xiàn)其他錯(cuò)誤,這就是 Windows Form 多線程編程的痛苦所在。筆者試過花很多時(shí)間來Debug 自己寫的Splash窗口突然消失的問題,結(jié)果還是失敗了:筆者在軟件的引導(dǎo)過程中,用另外一個(gè)線程里創(chuàng)建了一個(gè)Splash窗口來顯示歡迎信息,然后嘗試把主線程里引導(dǎo)的狀態(tài)直接寫入到Splash窗口上的控件中,開始還OK,可是過一會(huì)Spla
9、sh 窗口就莫明其妙消失了。理解了這一點(diǎn),我們應(yīng)該留意到,有時(shí)候即使沒有用來顯式創(chuàng)建一個(gè)線程,我們也可能因?yàn)槭褂昧水惒轿械?BeginInvoke 方法來隱式創(chuàng)建了線程 ( 從線程池里 ) ,在這種線程里也同樣不能調(diào)用 UI 線程所創(chuàng)建的控件的成員。第四,由于上述限制,我們可能會(huì)感到很不方便,的確,當(dāng)我們利用一個(gè)新創(chuàng)建的線程來執(zhí)行某些花時(shí)間的運(yùn)算時(shí),怎樣知道運(yùn)算進(jìn)度如何并通過UI 反映給用戶呢?解決方法很多! 比如熟悉多線程編程的用戶很快會(huì)想到,我們采用一些低級(jí)的同步方法,工作者線程把狀態(tài)保存到一個(gè)同步對(duì)象中,讓 UI 線程輪詢 (Polling) 該對(duì)象并反饋給用戶就可以了。不過,這還是挺
10、麻煩的,實(shí)際上不用這樣做,Control類 ( 及其派生類 ) 對(duì)象有一個(gè) Invoke方法很特別, 這是少數(shù)幾個(gè)不受線程限制的成員之一。我們前面說到, 絕對(duì)不要在任何其他線程里面調(diào)用非本線程創(chuàng)建的控件的成員時(shí),也說了“只有極個(gè)別情況例外”,這個(gè) Invoke方法就是極個(gè)別情況之一-Invoke方法可以從任何線程里面調(diào)用。下面我們來講解Invoke 方法。Invoke 方法的參數(shù)很簡單,一個(gè)委托,一個(gè)參數(shù)表( 可選 ) ,而 Invoke 方法的主要功能就是幫助你在UI 線程 ( 即創(chuàng)建控件的線程) 上調(diào)用委托所指定的方法。Invoke方法首先檢查發(fā)出調(diào)用的線程( 即當(dāng)前線程 ) 是不是 UI
11、 線程,如果是,直接執(zhí)行委托指向的方法,如果不是,它將切換到UI 線程,然后執(zhí)行委托指向的方法。不管當(dāng)前線程是不是UI 線程, Invoke都阻塞直到委托指向的方法執(zhí)行完畢,然后切換回發(fā)出調(diào)用的線程( 如果需要的話 ) ,返回。注意,使用 Invoke 方法時(shí), UI 線程不能處于阻塞狀態(tài)。以下MSDN里關(guān)于 Invoke 方法的說明:plain view plain copy在 CODE上查看代碼片派生到我的代碼片“控件上有四種方法可以安全地從任何線程進(jìn)行調(diào)用:InvokeEndInvoke和 CreateGraphics。對(duì)于所有其他方法調(diào)用,則應(yīng)使用調(diào)用、 BeginInvoke、(in
12、voke)方法之一封送對(duì)控件的線程的調(diào)用。委托可以是EventHandler的實(shí)例,在此情況下,發(fā)送方參數(shù)將包含此控件,而事件參數(shù)將包含。委托還可以是MethodInvoker的實(shí)例或采用void參數(shù)列表的其他任何委托。調(diào)用EventHandler或 MethodInvoker委托比調(diào)用其他類型的委托速度更快。”好了,說完 Invoke ,順便說說BeginInvoke ,毫無疑問這是Invoke 的異步版本 (Invoke是同步完成的 ) ,不過大家不要和上面的委托中的BeginInvoke混淆,兩者都是利用不同線程來完成工作,但是控件的BeginInvoke方法總是使用UI 線程,而其他的
13、異步委托調(diào)用方法則是利用線程池里的線程。相對(duì) Invoke 而言,使用 BeginInvoke 稍稍麻煩一點(diǎn),但還是那句話,異步比同步效果好,盡管復(fù)雜些。比如同步方法可能出現(xiàn)這樣一種死鎖情況: 工作者線程通過 Invoke 同步調(diào)用 UI 線程里的方法時(shí)會(huì)阻塞,而萬一 UI 線程正在等待工作者線程做某件事時(shí)怎么辦?因此,能夠使用異步方法時(shí)應(yīng)盡量使用異步方法。下面我們利用所學(xué)到的知識(shí)來改寫上面那個(gè)簡單的例子:csharp view plain copy在 CODE上查看代碼片派生到我的代碼片/ 這是由 UI 線程定義的 Label 控件private Label lblStatus;/ 以下方法不在 UI 線程上執(zhí)行private void RunsOnWorkerThread() DoSomethingSlow();/ Do UI update on UI thread obj
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 誠信的演講稿模板集合七篇
- 除數(shù)是兩位數(shù)的除法過關(guān)練習(xí)訓(xùn)練題大全附答案
- 運(yùn)動(dòng)會(huì)的廣播稿精
- 小學(xué)三年級(jí)數(shù)學(xué)因數(shù)中間或末尾有零的乘法單元考核例題帶答案
- 走進(jìn)春節(jié)綜合實(shí)踐活動(dòng)方案(10篇)
- 營銷活動(dòng)方案匯編15篇
- 防溺水教育觀后感合集15篇
- 重度低鉀血癥治療
- 人教版小學(xué)三年級(jí)數(shù)學(xué)上冊口算題練習(xí)
- 鐵路既有線安全技術(shù)規(guī)范
- 財(cái)務(wù)分析計(jì)算題13個(gè)
- 壓力容器年度檢查表
- 2023-2024學(xué)年湖北省洪湖市初中語文九年級(jí)下冊期末通關(guān)試題
- YY/T 1269-2015血液透析和相關(guān)治療用水處理設(shè)備常規(guī)控制要求
- DG-TJ 08-2198-2019 裝配式建筑評(píng)價(jià)標(biāo)準(zhǔn) 附條文說明
- GB/T 1.2-2020標(biāo)準(zhǔn)化工作導(dǎo)則第2部分:以ISO/IEC標(biāo)準(zhǔn)化文件為基礎(chǔ)的標(biāo)準(zhǔn)化文件起草規(guī)則
- 電氣接地施工規(guī)范
- VTE預(yù)防優(yōu)質(zhì)課件
- 湘教版《美術(shù)》六年級(jí)畢業(yè)班復(fù)習(xí)題
- 紀(jì)念抗日戰(zhàn)爭暨世界反法西斯戰(zhàn)爭勝利70周年主題班會(huì)課件
- 分娩恐懼量表
評(píng)論
0/150
提交評(píng)論