下載本文檔
版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
1、一 Thread 類庫Windows 是一個多任務的系統(tǒng),如果你使用的是windows 2000及其以上版本,你可以通過任務管理器查看當前系統(tǒng)運行的程序和進程。什么是進程呢?當一個程序開始運行時,它就是一個進程, 進程所指包括運行中的程序和程序所使用到的內存和系統(tǒng)資源。而一個進程又是由多個線程所組成的,線程是程序中的一個執(zhí)行流,每個線程都有自己的專有寄存器( 棧指針、程序計數(shù)器等) ,但代碼區(qū)是共享的,即不同的線程可以執(zhí)行同樣的函數(shù)。多線程是指程序中包含多個執(zhí)行流,即在一個程序中可以同時運行多個不同的線程來執(zhí)行不同的任務,也就是說允許單個程序創(chuàng)建多個并行執(zhí)行的線程來完成各自的任務。一 關于 T
2、hread 的說明在 framework class library 中,所有與多線程機制應用相關的類都是放在命名空間中的。其中提供 Thread 類用于創(chuàng)建線程, ThreadPool 類用于管理線程池等等,此外還提供解決了線程執(zhí)行安排, 死鎖,線程間通訊等實際問題的機制。 如果你想在你的應用程序中使用多線程,就必須包含這個類。 Thread 類有幾個至關重要的方法,描述如下:Start():啟動線程Sleep(int):靜態(tài)方法,暫停當前線程指定的毫秒數(shù)Abort():通常使用該方法來終止一個線程Suspend() :該方法并不終止未完成的線程,它僅僅掛起線程,以后還可恢復。Resume(
3、) :恢復被Suspend() 方法掛起的線程的執(zhí)行線程入口使程序知道該讓這個線程干什么事,在(delegate )來提供的, 你可以把 ThreadStart數(shù),當調用()方法后,線程就開始執(zhí)行C#中,線程入口是通過ThreadStart代理理解為一個函數(shù)指針,指向線程要執(zhí)行的函ThreadStart所代表或者說指向的函數(shù)。ThreadState在各種情況下的可能取值如下:Aborted :線程已停止AbortRequested :線程的 () 方法已被調用,但是線程還未停止Background :線程在后臺執(zhí)行,與屬性有關Running :線程正在正常運行Stopped :線程已經被停止S
4、topRequested :線程正在被要求停止Suspended:線程已經被掛起(此狀態(tài)下,可以通過調用Resume()方法重新運行)SuspendRequested :線程正在要求被掛起,但是未來得及響應Unstarted :未調用 () 開始線程的運行WaitSleepJoin:線程因為調用了Wait(),Sleep()或 Join()等方法處于封鎖狀態(tài)二 Winform 中使用的 thread首先可以看看最直接的方法, 也是 下支持的方法。 但請注意的是, 此方法在 以后就已經是一種錯誤的方法了。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 .這是因為以后加強了安全機制,不允許在winform 中直接跨線程訪問控件的屬性。那么怎么解決這個問題呢,下面提供幾種方案。第一種方案: 在 Thread 創(chuàng)建之氣, 將 設為 false 。 此代碼告訴編譯器:在這個類中我們不檢查跨線程的調用是否合法 (如果沒有加這句話運行也沒有異常, 那么說明系統(tǒng)以及默認的采用了不檢查的方式)。然而,這種方法不可取。我們查看CheckForIllegalCrossThreadCalls 這個屬性的定義,就會發(fā)現(xiàn)它是一個 static 的,也就
7、是說無論我們在項目的什么地方修改了這個值, 他就會在全局起作用。 而且像這種跨線程訪問是否存在異常, 我們通常都會去檢查。 如果項目中其他人修改了這個屬性, 那么我們的方案就失敗了,我們要采取另外的方案。第二種方案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)問題,但是這根本就是錯的,更糟糕的是,程序員在這里不會得到任何錯誤提示,一開始就上當受騙,之后會莫明其妙地發(fā)現(xiàn)其他錯誤,這就是 Windows Form 多線程編程的痛苦所在。筆者試過花很多時間來Debug 自己寫的Splash窗口突然消失的問題,結果還是失敗了:筆者在軟件的引導過程中,用另外一個線程里創(chuàng)建了一個Splash窗口來顯示歡迎信息,然后嘗試把主線程里引導的狀態(tài)直接寫入到Splash窗口上的控件中,開始還OK,可是過一會Spla
9、sh 窗口就莫明其妙消失了。理解了這一點,我們應該留意到,有時候即使沒有用來顯式創(chuàng)建一個線程,我們也可能因為使用了異步委托的 BeginInvoke 方法來隱式創(chuàng)建了線程 ( 從線程池里 ) ,在這種線程里也同樣不能調用 UI 線程所創(chuàng)建的控件的成員。第四,由于上述限制,我們可能會感到很不方便,的確,當我們利用一個新創(chuàng)建的線程來執(zhí)行某些花時間的運算時,怎樣知道運算進度如何并通過UI 反映給用戶呢?解決方法很多! 比如熟悉多線程編程的用戶很快會想到,我們采用一些低級的同步方法,工作者線程把狀態(tài)保存到一個同步對象中,讓 UI 線程輪詢 (Polling) 該對象并反饋給用戶就可以了。不過,這還是挺
10、麻煩的,實際上不用這樣做,Control類 ( 及其派生類 ) 對象有一個 Invoke方法很特別, 這是少數(shù)幾個不受線程限制的成員之一。我們前面說到, 絕對不要在任何其他線程里面調用非本線程創(chuàng)建的控件的成員時,也說了“只有極個別情況例外”,這個 Invoke方法就是極個別情況之一-Invoke方法可以從任何線程里面調用。下面我們來講解Invoke 方法。Invoke 方法的參數(shù)很簡單,一個委托,一個參數(shù)表( 可選 ) ,而 Invoke 方法的主要功能就是幫助你在UI 線程 ( 即創(chuàng)建控件的線程) 上調用委托所指定的方法。Invoke方法首先檢查發(fā)出調用的線程( 即當前線程 ) 是不是 UI
11、 線程,如果是,直接執(zhí)行委托指向的方法,如果不是,它將切換到UI 線程,然后執(zhí)行委托指向的方法。不管當前線程是不是UI 線程, Invoke都阻塞直到委托指向的方法執(zhí)行完畢,然后切換回發(fā)出調用的線程( 如果需要的話 ) ,返回。注意,使用 Invoke 方法時, UI 線程不能處于阻塞狀態(tài)。以下MSDN里關于 Invoke 方法的說明:plain view plain copy在 CODE上查看代碼片派生到我的代碼片“控件上有四種方法可以安全地從任何線程進行調用:InvokeEndInvoke和 CreateGraphics。對于所有其他方法調用,則應使用調用、 BeginInvoke、(in
12、voke)方法之一封送對控件的線程的調用。委托可以是EventHandler的實例,在此情況下,發(fā)送方參數(shù)將包含此控件,而事件參數(shù)將包含。委托還可以是MethodInvoker的實例或采用void參數(shù)列表的其他任何委托。調用EventHandler或 MethodInvoker委托比調用其他類型的委托速度更快?!焙昧耍f完 Invoke ,順便說說BeginInvoke ,毫無疑問這是Invoke 的異步版本 (Invoke是同步完成的 ) ,不過大家不要和上面的委托中的BeginInvoke混淆,兩者都是利用不同線程來完成工作,但是控件的BeginInvoke方法總是使用UI 線程,而其他的
13、異步委托調用方法則是利用線程池里的線程。相對 Invoke 而言,使用 BeginInvoke 稍稍麻煩一點,但還是那句話,異步比同步效果好,盡管復雜些。比如同步方法可能出現(xiàn)這樣一種死鎖情況: 工作者線程通過 Invoke 同步調用 UI 線程里的方法時會阻塞,而萬一 UI 線程正在等待工作者線程做某件事時怎么辦?因此,能夠使用異步方法時應盡量使用異步方法。下面我們利用所學到的知識來改寫上面那個簡單的例子: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)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 帶貨主播試用期轉正工作總結(6篇)
- 初級焊工安全知識培訓
- 連續(xù)性血液凈化治療腎衰竭合并重癥心力衰竭的價值
- 智研咨詢-中國數(shù)字生活行業(yè)市場調查、產業(yè)鏈全景、需求規(guī)模預測報告
- 車載SINS-GNSS緊組合導航系統(tǒng)研究
- 基于混合樣本的對抗對比域適應算法及理論
- 產前檢查科護士的工作概覽
- 打造專業(yè)化服務團隊的目標計劃
- 二零二五年度商業(yè)綜合體物業(yè)施工安全管理合同范本3篇
- 2025版物流運輸車隊與保險企業(yè)合作合同3篇
- 完整版秸稈炭化成型綜合利用項目可行性研究報告
- 2025中國海油春季校園招聘1900人高頻重點提升(共500題)附帶答案詳解
- 膽汁淤積性肝硬化護理
- 油氣行業(yè)人才需求預測-洞察分析
- 《數(shù)據(jù)采集技術》課件-Scrapy 框架的基本操作
- (2024)河南省公務員考試《行測》真題及答案解析
- 醫(yī)療保險結算與審核制度
- 中央空調售后服務普及培訓螺桿機篇
- 中國航天知識
- 第8課紅樓春趣同步練習(含答案)
- 小學生體育鍛煉習慣的培養(yǎng)
評論
0/150
提交評論