C#實(shí)現(xiàn)多線程啟動停止暫停繼續(xù)的示例代碼
大部分初學(xué)者在學(xué)習(xí)C#上位機(jī)編程時,多線程是一個很難逾越的鴻溝,不合理地使用多線程,會導(dǎo)致經(jīng)常出現(xiàn)各種奇怪的問題,這也是很多初學(xué)者不敢使用多線程的原因。但是在實(shí)際開發(fā)中,多線程是一個不可避免的技術(shù)棧,基本上每個項(xiàng)目都會使用到,因此學(xué)好多線程技術(shù),很重要。
一、多線程原理
首先,我們要了解什么是多線程,多線程是一種技術(shù),能夠讓一個程序同時運(yùn)行多個獨(dú)立的執(zhí)行流程,這個執(zhí)行流程即線程,這樣就可以提高程序的并發(fā)性和效率,使程序能夠更有效地利用系統(tǒng)資源。
打個比方,剛創(chuàng)業(yè)的時候,我們可能是一個人身兼多職,既要對接業(yè)務(wù),又要做技術(shù),還需要管理財(cái)務(wù),雖然你可以同時做這些事情,但畢竟只有一個人,這里的同時,其實(shí)是靠“時間管理”來實(shí)現(xiàn)的,這就是單核CPU實(shí)現(xiàn)多線程的原理,依靠時間片切換來實(shí)現(xiàn)多個任務(wù),這個時間片很短,通常在10-100ms數(shù)量級,因此,讓我們感覺是同時進(jìn)行的。
隨著技術(shù)的不斷發(fā)展,現(xiàn)在的計(jì)算機(jī)CPU基本上都是多核的。8核、16核,都很常見,多核意味著有多個核心,可以同時運(yùn)行多個任務(wù)。
因此,多核CPU上的多線程才是真正的多線程,它能讓你的多段邏輯同時工作,多線程,可以真正發(fā)揮出多核CPU的優(yōu)勢來,達(dá)到充分利用CPU的目的。
如果你做項(xiàng)目不使用多線程,不僅是技術(shù)的問題,也是對電腦資源的極大浪費(fèi),就像買了一輛性能車,但是只用來日常代步。
二、多線程發(fā)展
我們知道了多線程技術(shù)可以保證我們代碼的高效運(yùn)行,提高CPU資源的使用率,為什么很多人不敢使用,主要是因?yàn)槎嗑€程如果使用不當(dāng),容易出現(xiàn)各種奇怪的問題。
我們必須要明確一點(diǎn),多線程是“不可控的”,不要把多線程當(dāng)做一個開關(guān),需要的時候就開一下,不需要的時候就關(guān)閉一下。從微觀角度來看,多線程是靠CPU調(diào)度來實(shí)現(xiàn)的,我們常說的開啟多線程,只是告訴CPU,這個線程可以開了,但是至于是立即開,還是等一會再開,這個是由CPU調(diào)度決定的,對于關(guān)閉多線程也是一樣。
我們后續(xù)提到的控制多線程啟動、停止、暫停、繼續(xù),這些都是.NET框架中提供的一些接口(方法)給開發(fā)人員,這樣程序員就可以間接地實(shí)現(xiàn)多線程。
微軟的多線程技術(shù)也是在一直發(fā)展中,在.NET 1.0中就出現(xiàn)了多線程Thread,到2.0時推出了ThreadPool線程池,再到3.0是出現(xiàn)了Task,Task也是我們目前使用比較多的,Task被稱之為多線程的最佳實(shí)踐,再到4.0時推出Parallel并行編程,再到4.5推出async/await語法糖,它讓我們可以用同步方法來實(shí)現(xiàn)異步編程。
三、多線程啟停
Task是我們使用多線程開發(fā)中經(jīng)常使用的一個類,這個類中提供了豐富的API函數(shù),讓我們可以很方便地對多線程進(jìn)行管理,包括開啟多線程了,就有很多種方法,比如Task.Run、Task.Factory.StartNew、Start等,由于篇幅有限,這里以其中一種進(jìn)行說明。
我們來使用多線程實(shí)現(xiàn)一個簡單的案例,我們來做一個線程任務(wù),這個任務(wù)很簡單,就是讓一個值類型的變量,每間隔100ms,自增一次,到一個值后,再0開始重新計(jì)數(shù),然后將這個值顯示在界面上,界面如下所示:
所以該任務(wù)執(zhí)行代碼如下:
我們可以看到在方法里調(diào)用了一個cts對象,這個對象就是CancellationTokenSource的對象,因此我們需要創(chuàng)建一個CancellationTokenSource對象cts,同時在屬性CurrentValue中,要顯示控件的值,這里需要用到委托實(shí)現(xiàn)跨線程訪問的問題,這個我們后續(xù)專題講解,代碼如下:
然后在啟動線程按鈕的事件里,編寫代碼如下:
停止線程按鈕的事件里,只需要調(diào)用cts的Cancel方法即可:
我們可以看到,這里就是通過cts來控制cts的IsCancellationRequested屬性,進(jìn)而實(shí)現(xiàn)多線程的控制,這里的cts.IsCancellationRequested類似于一個布爾類型的標(biāo)志位,但是CancellationTokenSource的作用不僅如此,還可以在此基礎(chǔ)上實(shí)現(xiàn)多線程超時判斷,注冊事件等更復(fù)雜的多線程操作。
四、多線程暫停繼續(xù)
多線程的暫停繼續(xù),.NET為我們提供了另外一個對象——ManualResetEvent,這個對象會有一個值,這個值是布爾類型,就像一個門閘一樣,True是打開門閘,F(xiàn)alse是關(guān)閉門閘,所以想要暫停多線程就調(diào)用這個對象的Reset方法,想要繼續(xù)多線程就調(diào)用這個對象的Set方法,使用非常簡單。
首先我們創(chuàng)建一下這個對象,可以通過構(gòu)造方法,給這個對象賦初始值,我這里為True,這樣就能直接運(yùn)行,不會阻塞,代碼如下:
但是如果希望這個對象與多線程有所聯(lián)系,必須要在多線程的方法里體現(xiàn)這個對象的作用,這個是調(diào)用這個對象的WaitOne方法,表示在調(diào)用的地方阻塞住,通過判斷True或者False來決定是否繼續(xù)執(zhí)行,就像大家開車過高速收費(fèi)站一樣,即使現(xiàn)在普遍采用ETC了,在入口也需要減速,有一個ETC識別的過程,識別成功才會抬桿,識別不對,桿子是不會自動抬起的,這個是一樣的道理。
所以線程執(zhí)行代碼修改如下:
對比一下,其實(shí)就是加了一個manual.WaitOne()。
線程暫停繼續(xù)代碼如下:
暫停繼續(xù)的使用除了ManualResetEvent,還有一個AutoResetEvent,AutoResetEvent和ManualResetEvent的用法基本上是一樣的,這里就不過多贅述,大家可以自己嘗試一下。
這兩者的區(qū)別在于一個是手動,一個是自動,AutoResetEvent會在置位之后自動復(fù)位,這樣體現(xiàn)在多線程里,就是會只執(zhí)行一次,就像大家進(jìn)小區(qū)一樣,如果有10輛車在排隊(duì),這時候如果自動模式,每次都要抬桿落桿,每次只允許進(jìn)一輛車,如果是手動模式,可以由保安控制門閘打開,等10輛車都進(jìn)去之后,再由保安將門閘關(guān)閉。
到此這篇關(guān)于C#實(shí)現(xiàn)多線程啟動停止暫停繼續(xù)的示例代碼的文章就介紹到這了,更多相關(guān)C# 多線程啟動停止內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
使用Nopcommerce為商城添加滿XX減XX優(yōu)惠券功能
中秋國慶節(jié)眼看到跟前了,很多商城都借此機(jī)會搞促銷活動,什么滿200減80送優(yōu)惠券等活動,基于后臺程序是怎么實(shí)現(xiàn)的呢?下面腳本之家小編帶領(lǐng)大家一起學(xué)習(xí)吧2015-09-09C#結(jié)合JavaScript對Web控件進(jìn)行數(shù)據(jù)輸入驗(yàn)證的實(shí)現(xiàn)方法
在 Web 應(yīng)用的錄入界面,數(shù)據(jù)驗(yàn)證是一項(xiàng)重要的實(shí)現(xiàn)功能,數(shù)據(jù)驗(yàn)證是指確認(rèn) Web 控件輸入或選擇的數(shù)據(jù),本文我們將介紹如何通過C# 后端及JavaScript 前端對 Web 控件進(jìn)行數(shù)據(jù)輸入有效性的驗(yàn)證,感興趣的朋友可以參考一下2024-05-05C#字符串與數(shù)值類型、字節(jié)數(shù)組的互相轉(zhuǎn)換實(shí)戰(zhàn)案例
最近由于編程的需要,對C#的類型轉(zhuǎn)換做了一些研究,下面這篇文章主要給大家介紹了關(guān)于C#字符串與數(shù)值類型、字節(jié)數(shù)組的互相轉(zhuǎn)換的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-06-06基于NET?Core?的Nuget包制作、發(fā)布和運(yùn)用流程解析(完整過程)
這篇文章主要介紹了基于NET?Core?的Nuget包制作、發(fā)布和運(yùn)用流程,本文通過圖文并茂的形式給大家介紹了Nuget包制作過程,感興趣的朋友跟隨小編一起看看吧2022-02-02