天天看點

C# WinForm多線程開發(一) Thread類庫

[摘要]本文介紹c#

winform多線程開發之thread類庫,并提供簡單的示例代碼供參考。

windows是一個多任務的系統,如果你使用的是windows 2000及其以上版本,你可以通過任務管理器檢視目前系統運作的程式和程序。什麼是程序呢?當一個程式開始運作時,它就是一個程序,程序所指包括運作中的程式和程式所使用到的記憶體和系統資源。而一個程序又是由多個線程所組成的,線程是程式中的一個執行流,每個線程都有自己的專有寄存器(棧指針、程式計數器等),但代碼區是共享的,即不同的線程可以執行同樣的函數。多線程是指程式中包含多個執行流,即在一個程式中可以同時運作多個不同的線程來執行不同的任務,也就是說允許單個程式建立多個并行執行的線程來完成各自的任務。

在.net framework class library中,所有與多線程機制應用相關的類都是放在system.threading命名空間中的。其中提供thread類用于建立線程,threadpool類用于管理線程池等等,此外還提供解決了線程執行安排,死鎖,線程間通訊等實際問題的機制。如果你想在你的應用程式中使用多線程,就必須包含這個類。thread類有幾個至關重要的方法,描述如下:

start():啟動線程 

sleep(int):靜态方法,暫停目前線程指定的毫秒數 

abort():通常使用該方法來終止一個線程 

suspend():該方法并不終止未完成的線程,它僅僅挂起線程,以後還可恢複。 

resume():恢複被suspend()方法挂起的線程的執行 

線程入口使程式知道該讓這個線程幹什麼事,在c#中,線程入口是通過threadstart代理(delegate)來提供的,你可以把threadstart了解為一個函數指針,指向線程要執行的函數,當調用 thread.start()方法後,線程就開始執行threadstart所代表或者說指向的函數。

threadstate在各種情況下的可能取值如下:

aborted:線程已停止 

abortrequested:線程的thread.abort()方法已被調用,但是線程還未停止 

background:線程在背景執行,與屬性thread.isbackground有關 

running:線程正在正常運作 

stopped:線程已經被停止 

stoprequested:線程正在被要求停止 

suspended:線程已經被挂起(此狀态下,可以通過調用resume()方法重新運作) 

suspendrequested:線程正在要求被挂起,但是未來得及響應 

unstarted:未調用thread.start()開始線程的運作 

waitsleepjoin:線程因為調用了wait(),sleep()或join()等方法處于封鎖狀态 

首先可以看看最直接的方法,也是.net 1.0下支援的方法。但請注意的是,此方法在.net 2.0以後就已經是一種錯誤的方法了。

這段code 在vs2005或者2008上都抛出異常 :cross-thread operation not valid:control 'textbox1' accessed from a thread other than the thread it was created on . 這是因為.net 2.0以後加強了安全機制,不允許在winform中直接跨線程通路控件的屬性。那麼怎麼解決這個問題呢,下面提供幾種方案。

第一種方案: 在thread建立之氣,将control.checkforillegalcrossthreadcalls 設為 false。 此代碼告訴編譯器:在這個類中我們不檢查跨線程的調用是否合法(如果沒有加這句話運作也沒有異常,那麼說明系統以及預設的采用了不檢查的方式)。然而,這種方法不可取。我們檢視checkforillegalcrossthreadcalls 這個屬性的定義,就會發現它是一個static的,也就是說無論我們在項目的什麼地方修改了這個值,他就會在全局起作用。而且像這種跨線程通路是否存在異常,我們通常都會去檢查。如果項目中其他人修改了這個屬性,那麼我們的方案就失敗了,我們要采取另外的方案。

第二種方案

通過上叙代碼,可以看到問題已經被解決了,通過等待異步,我們就不會總是持有主線程的控制,這樣就可以在不發生跨線程調用異常的情況下完成多線程對winform多線程控件的控制了。