C#線程開(kāi)發(fā)之System.Thread類詳解
一、屬性
- CurrentContext 獲取線程正在其中執(zhí)行的當(dāng)前上下文。
- ExecutionContext 獲取 ExecutionContext 對(duì)象,該對(duì)象包含有關(guān)當(dāng)前線程的各種上下文的信息。
- CurrentCulture 獲取或設(shè)置當(dāng)前線程的區(qū)域性。
- CurrentUICulture 獲取或設(shè)置資源管理器使用的當(dāng)前區(qū)域性以便在運(yùn)行時(shí)查找區(qū)域性特定的資源。
- CurrentThread 獲取當(dāng)前正在運(yùn)行的線程。
- IsAlive 獲取指示當(dāng)前線程的執(zhí)行狀態(tài)的值。
- IsBackground 獲取或設(shè)置一個(gè)值,該值指示某個(gè)線程是否為后臺(tái)線程。
- IsThreadPoolThread 獲取指示線程是否屬于托管線程池的值。
- ManagedThreadId 獲取當(dāng)前托管線程的唯一標(biāo)識(shí)符。
- Name 獲取或設(shè)置線程的名稱。
- Priority 獲取或設(shè)置指示線程的調(diào)度優(yōu)先級(jí)的值。
- ThreadState 獲取一個(gè)值,該值包含當(dāng)前線程的狀態(tài)。
二、創(chuàng)建和控制線程
Thread 類的構(gòu)造函數(shù)重載為接受ThreadStart和ParameterizedThreadStart類型的委托參數(shù)。
ThreadStart委托定義了一個(gè)返回類型為void的無(wú)參數(shù)方法。在創(chuàng)建了 Thread對(duì)象后,就可以用Start()方法啟動(dòng)線程:
class Program { static void Main() { var t1 = new Thread(ThreadMain); t1.Start(); Console.WriteLine("This is the main thread."); } static void ThreadMain() { Console.WriteLine("Running in a thread."); } }
Lambda表達(dá)式還可以與Thread類一起 使用,將線程方法的實(shí)現(xiàn)代碼傳送給Thread構(gòu)造函數(shù)的實(shí)參:
static void Main() { var t1 = new Thread(() => Console.WriteLine("running in a thread, id: {0}",Thread.CurrentThread.ManagedThreadId)); t1.Start(); Console.WriteLine("This is the main thread, id: {0}", Thread.CurrentThread.ManagedThreadId); }
三、給線程傳遞參數(shù)
給線程傳遞一些數(shù)據(jù)可以采用兩種方式。
1、ParameterizedThreadStart委托參數(shù)
要給線程傳遞數(shù)據(jù),需要某個(gè)存儲(chǔ)數(shù)據(jù)的類或結(jié)構(gòu)。這里定義了包含字符串的Data結(jié)構(gòu),但可以傳遞任意對(duì)象.
static void Main() { var d = new Data { Message = "Info" }; var t2 = new Thread(ThreadMainWithParameters);//ParameterizedThreadStart委托實(shí)例 t2.Start(d); } static void ThreadMainWithParameters(object o)//如果使用了 ParameterizedThreadStart委托,線程的入口點(diǎn)必須有一個(gè)object類型的參數(shù),且返回類型為void。 { Data d = (Data)o; Console.WriteLine("Running in a thread, received {0}", d.Message); } public struct Data { public string Message; }
2、創(chuàng)建一個(gè)自定義類,把線程的方法定義為實(shí)例方法
給新線程傳遞數(shù)據(jù)的另一種方式是定義一個(gè)類(參見(jiàn)MyThread類),在其中定義需要的字段,將線程的調(diào)用的方法定義為類的一個(gè)實(shí)例方法:
static void Main() { var obj = new MyThread("info"); var t3 = new Thread(obj.ThreadMain);//實(shí)例方法 t3.Start(); } //實(shí)例方法 public class MyThread { private string data; public MyThread(string data) { this.data = data; } public void ThreadMain() { Console.WriteLine("Running in a thread, data: {0}", data); } }
四、后臺(tái)線程
只要有一個(gè)前臺(tái)線程在運(yùn)行,應(yīng)用程序的進(jìn)程就在運(yùn)行。
如果多個(gè)前臺(tái)線程在運(yùn)行,而Main()方法結(jié)束了,應(yīng)用程序的進(jìn)程就仍然是激活的,直到所有前臺(tái)線程完成其任務(wù)為止。
在默認(rèn)情況下,用Thread類創(chuàng)建的線程是前臺(tái)線程。線程池屮的線程總是后臺(tái)線程。
在用Thread類創(chuàng)建線程時(shí),可以設(shè)置IsBackground屬性,以確定該線程是前臺(tái)線程還是后臺(tái)線程。
五、線程的優(yōu)先級(jí)
在Thread類中,可以設(shè)置Priority屬性,以影響線程的基本優(yōu)先級(jí)。Priority屬性需要ThreadPriority 枚舉定義的一個(gè)值。定義的級(jí)別有Highest、AboveNomal、BelowNormal和Lowest。
六、控制線程
- 調(diào)用Thread對(duì)象的Start()方法,可以創(chuàng)建線程。但是,在調(diào)用Start()方法后,新線程仍不是處于Running狀態(tài),而是處于Unstarted狀態(tài)。只要操作系統(tǒng)的線程調(diào)度器選擇了要運(yùn)行的線程,線程就會(huì)改為Running狀態(tài)。讀取Thread.ThreadState屬性,就可以獲得線程的當(dāng)前狀態(tài)。
- 使用ThreadSleep()方法,會(huì)使線程處于WaitSleepJoin狀態(tài),在經(jīng)歷Sleep()方法定義的時(shí)間段后,線程就會(huì)等待再次被喚醒。
- 要停止另一個(gè)線程,可以調(diào)用Thread.Abort() 方法。調(diào)用這個(gè)方法時(shí),會(huì)在接到終止命令的線程中拋出一個(gè)ThreadAbortExcepticm類型的異常。用一個(gè)處理程序捕獲這個(gè)異常,線程可以在結(jié)束前完成一些淸理工作。線程還可以在接收到調(diào)用Thread.ResetAbort()方法的結(jié)果ThreadAbortExcepdon 異常后繼續(xù)運(yùn)行。如果線程沒(méi)有重置終止,接收到終止請(qǐng)求的線程的狀態(tài)就從AbortRequested改為 Aborted。
- 如果需要等待線程的結(jié)束,就可以調(diào)用Thread.Join()方法。Thread.Join()方法會(huì)停止當(dāng)前線程, 并把它設(shè)置為WaitSleepJoin狀態(tài),直到加入的線程完成為止。
public class Worker { // 此方法將在線程啟動(dòng)時(shí)調(diào)用。 public void DoWork() { while (!_shouldStop) { Console.WriteLine("工作線程: working..."); } Console.WriteLine("工作線程:正常停止"); } public void RequestStop() { _shouldStop = true; } // Volatile用于提示編譯器這個(gè)數(shù)據(jù)成員將被多個(gè)線程訪問(wèn)。 private volatile bool _shouldStop; } static void Main() { // 創(chuàng)建thread對(duì)象,但這不會(huì)啟動(dòng)線程。 Worker workerObject = new Worker(); Thread workerThread = new Thread(workerObject.DoWork); // 啟動(dòng)工作線程。 workerThread.Start(); Console.WriteLine("main thread: 啟動(dòng)工作線程..."); // 循環(huán),直到工作線程激活。 while (!workerThread.IsAlive) ; // 將主線程休眠1毫秒,讓工作線程做一些工作: Thread.Sleep(1); // 請(qǐng)求工作線程停止自身: workerObject.RequestStop();//workerObject.Abort() //使用Join方法阻塞當(dāng)前線程,直到工作線程執(zhí)行完畢才往下執(zhí)行 workerThread.Join(); Console.WriteLine("main thread: 工作線程已經(jīng)終止."); }
七、使用線程實(shí)現(xiàn)回調(diào)
//定義一個(gè)委托實(shí)現(xiàn)回調(diào)函數(shù) public delegate void CallBackDelegate(string message); void Main() { //委托實(shí)現(xiàn)方法和定義線程 CallBackDelegate cbd = CallBack; Thread thread = new Thread(initFtpParam); thread.Start(cbd); } /// <summary> /// 線程方法 /// </summary> /// <param name="obj"></param> public void initFtpParam(object obj) { CallBackDelegate callBackDelegate = obj as CallBackDelegate; callBackDelegate("aa");//執(zhí)行委托 } /// <summary> /// 回調(diào)方法 /// </summary> /// <param name="message"></param> private void CallBack(string message) { Console.Write(message); }
八、區(qū)域性和線程
- CurrentUICulture屬性可返回當(dāng)前用戶界面區(qū)域性。該屬性由 ResourceManager 類用于在運(yùn)行時(shí)查找區(qū)域性特定資源。
可以使用非特定區(qū)域性、特定區(qū)域性或 InvariantCulture 來(lái)設(shè)置 CurrentUICulture 屬性。
默認(rèn)值是操作系統(tǒng)用戶界面語(yǔ)言。 - CurrentCulture屬性用來(lái)決定諸如貨幣、數(shù)字和日期如何格式化。
CurrentCulture 屬性不是一個(gè)語(yǔ)言設(shè)置。它僅包含與地理區(qū)域的標(biāo)準(zhǔn)設(shè)置相關(guān)的數(shù)據(jù)。因此,只能將 CurrentCulture 屬性設(shè)置為特定區(qū)域性,比如"fr-FR"或 InvariantCulture。
默認(rèn)值是操作系統(tǒng)的User Locale,我們可以在控制面板里設(shè)置。CultureInfo.UseUserOverride屬性指示是否使用用戶在控制面板自定義的 數(shù)字、符號(hào)、日期、貨幣等的格式。
1、.NET4.5之前,只能用以下代碼只能針對(duì)單個(gè)線程,如果每次執(zhí)行線程 都要重新設(shè)置一下。。。
新開(kāi)一個(gè)新線程,默認(rèn)的CurrentCulture為系統(tǒng)的Culture,如果要改變當(dāng)前線程的Culture,需要在線程中修改 Thread.CurrentCulture值來(lái)實(shí)現(xiàn)。
m.Threading.Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo("en-US"); System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo("en-US");
2、如果使用的.net環(huán)境是4.5及以上版本,CultureInfo提供了兩個(gè)靜態(tài)屬性DefaultThreadCulture和DefaultThreadUICulture,一處修改即可實(shí)現(xiàn)所有的未顯式設(shè)置Thread.CurrentCulture的線程都使用這個(gè)Default值。
System.Globalization.CultureInfo.DefaultThreadCurrentCulture = new System.Globalization.CultureInfo("en-US"); System.Globalization.CultureInfo.DefaultThreadCurrentUICulture = new System.Globalization.CultureInfo("en-US");
到此這篇關(guān)于C#線程開(kāi)發(fā)之System.Thread類的文章就介紹到這了。希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
利用微軟com組件mstscax.dll實(shí)現(xiàn)window7遠(yuǎn)程桌面功能
利用微軟提供的com組件mstscax.dll實(shí)現(xiàn)類似window遠(yuǎn)程桌面功能,大家參考使用吧2013-12-12C# 多線程編程技術(shù)基礎(chǔ)知識(shí)入門(mén)
這篇文章主要介紹了C# 多線程編程技術(shù)基礎(chǔ)知識(shí),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2020-02-02C# 使用SDL2實(shí)現(xiàn)Mp4文件播放音視頻操作
這篇文章主要介紹了C# 使用SDL2實(shí)現(xiàn)Mp4文件播放音視頻操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-12-12C#利用Random得隨機(jī)數(shù)求均值、方差、正態(tài)分布的方法
這篇文章主要介紹了C#利用Random得隨機(jī)數(shù)求均值、方差、正態(tài)分布的方法,涉及C#數(shù)學(xué)運(yùn)算及概率統(tǒng)計(jì)的相關(guān)技巧,需要的朋友可以參考下2015-05-05