c# Thread類的用法詳解
Thread類相對于線程池中的線程,使用者有更多的控制權(quán)。該類允許創(chuàng)建前臺線程,設(shè)置線程優(yōu)先級等。Thread類的構(gòu)造函數(shù)重載為接受ThreadStart和ParameterizedThreadStart類型的委托參數(shù)。
1、給線程傳遞數(shù)據(jù)
給線程傳遞數(shù)據(jù)的兩種方式:
1.使用帶ParameterizedThreadStart委托參數(shù)的Thread構(gòu)造函數(shù):
//定義一個數(shù)據(jù)類型,傳遞給線程 public struct Data { public string Message; } //創(chuàng)建一個方法,將方法給線程的ParameterizedThreadStart委托 static void ThreadMainWithParameters(object obj) { Data d = (Data)obj; Console.WriteLine("Running in a thread, received {0}", d.Message); } static void Main() { Data d = new Data { Message = "Info" };//創(chuàng)建一個數(shù)據(jù)實例 Thread t2 = new Thread(ThreadMainWithParameters);//創(chuàng)建線程 t2.Start(d);//啟動線程,并傳遞參數(shù) }
2.自定義一個類,把線程的方法定義為實例方法,然后初始化實例的數(shù)據(jù)后啟動線程。
//定義一個類,用于存放線程需要的數(shù)據(jù)和線程啟動的方法 public class MyThread { private string data;//線程數(shù)據(jù) public MyThread(string data) { this.data = data; } //線程啟動方法 public void ThreadMain() { Console.WriteLine("Running in a thread, data: {0}", data); } } static void Main() { MyThread obj = new MyThread("info");//創(chuàng)建實例信息 Thread t3 = new Thread(obj.ThreadMain);//啟動實例方法 t3.Start(); }
2、后臺線程
如果應(yīng)用程序內(nèi)有任何一個前臺線程在運行,那么應(yīng)用程序就在運行。Thread類創(chuàng)建的線程默認(rèn)時前臺線程,線程池中創(chuàng)建的線程是后臺線程。在使用Thread類創(chuàng)建線程時,可以設(shè)置IsBackground屬性,以設(shè)置創(chuàng)建的Thread線程時后臺線程還是前臺線程。例如:
//創(chuàng)建線程方法,以在主線程中調(diào)用 static void ThreadMain() { Console.WriteLine("Thread {0} started", Thread.CurrentThread.Name); Thread.Sleep(3000); Console.WriteLine("Thread {0} completed", Thread.CurrentThread.Name); } static void Main() { Thread t1 = new Thread(ThreadMain); t1.Name = "MyNewThread"; t1.Start(); Thread.Sleep(100); Console.WriteLine("Main thread ending now..."); /*******************輸出******************** * Thread MyNewThread started * Main thread ending now... * Thread MyNewThread completed * *****************************************/ }
可以看到,主線程先完成任務(wù)。但是主線程內(nèi)啟動的新線程是前臺線程(默認(rèn)),導(dǎo)致主線程結(jié)束任務(wù)后,新線程仍在寫入控制臺輸出。如果在線程啟動前,將線程的IsBackground屬性設(shè)置為true,主線程結(jié)束時,會終止新線程的執(zhí)行(不論是否完成任務(wù))。
static void Main() { Thread t1 = new Thread(ThreadMain); t1.Name = "MyNewThread"; t1.IsBackground = true; t1.Start(); Thread.Sleep(100); Console.WriteLine("Main thread ending now..."); /*******************輸出******************** * Thread MyNewThread started * Main thread ending now... * *****************************************/ }
后臺線程適合用于完成后臺任務(wù)。
3、線程的優(yōu)先級
線程由操作系統(tǒng)調(diào)度。給線程指定優(yōu)先級,將影響線程調(diào)度順序。優(yōu)先級越高的線程,將會得到系統(tǒng)優(yōu)先調(diào)度在CPU上運行。如果線程在等待資源,它就會停止運行,并釋放CPU。
線程必須等待的可能原因:響應(yīng)睡眠指令、等待磁盤I/O完成、等待網(wǎng)絡(luò)包到達(dá)等。如果線程不主動釋放CPU,線程調(diào)度器就會搶占該線程。線程由一個時間量,它可以持續(xù)使用CPU,直到時間到達(dá)(如果沒有更高優(yōu)先級的線程時)。如果優(yōu)先級相同的多個線程等待CPU,線程調(diào)度器會使用一個循環(huán)調(diào)度原則,將CPU逐一交個線程使用。如果線程被其他線程搶占,那么它會排隊到最后去。
只有優(yōu)先級相同的多個線程同時在運行時,才能用上時間量和循環(huán)規(guī)則。優(yōu)先級是動態(tài)的:如果線程是CPU密集型,一直需要CPU,而且不等待資源,其優(yōu)先級就降低為用該線程定義的基本優(yōu)先級;如果線程在等待資源,它的優(yōu)先級會提高。由于優(yōu)先級的提高,所以線程可能在下一等待結(jié)束時獲得CPU。
線程的Priority屬性,可以設(shè)置線程的優(yōu)先級。線程指定優(yōu)先級時,可能降低其他線程的運行概率。所以,可以根據(jù)需要短暫改變優(yōu)先級。
4、控制線程
調(diào)用Thread對象的Start()方法可以創(chuàng)建線程。但是,新線程并不是出于Running狀態(tài),而是Unstarted狀態(tài)。當(dāng)線程調(diào)度器調(diào)用線程時,線程則會改為Running狀態(tài)。其ThreadState屬性可以獲得線程的狀態(tài)。
線程類的靜態(tài)方法Sleep(),會使線程處于WaitSleepJoin狀態(tài),在等待一段時間后,線程將再次被喚醒。
如果要停止一個線程,可以調(diào)用方法Abort()。調(diào)用該方法,會在接到終止命令的線程中拋出ThreadAbortException類型異常。捕獲該異常,可以在線程結(jié)束前做一些清理工作。如果再調(diào)用方法ResetAbort(),可能有機會再收到異常后繼續(xù)運行。如果線程沒有重置,接收到終止請求的線程的狀態(tài)就從AbortRequested改為Aborted。
調(diào)用Join()方法可以等待線程的結(jié)束。該方法會停止當(dāng)前線程,并把它設(shè)置為WaitSleepJoin狀態(tài),直到加入的線程完成。
以上就是c# Thread類的用法詳解的詳細(xì)內(nèi)容,更多關(guān)于c# Thread類的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
DataGridView自定義單元格表示值、Error圖標(biāo)顯示的方法介紹
這篇文章介紹了DataGridView自定義單元格表示值、Error圖標(biāo)顯示的方法,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-02-02C# 連接SQL數(shù)據(jù)庫的方法及常用連接字符串
這篇文章主要介紹了C# 連接SQL數(shù)據(jù)庫的方法及常用連接字符串,有需要的朋友可以參考一下2014-01-01