您好,登錄后才能下訂單哦!
今天小編給大家分享一下C#怎么優(yōu)雅地終止線(xiàn)程的相關(guān)知識(shí)點(diǎn),內(nèi)容詳細(xì),邏輯清晰,相信大部分人都還太了解這方面的知識(shí),所以分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后有所收獲,下面我們一起來(lái)了解一下吧。
現(xiàn)在有一個(gè)需求:有一個(gè)后臺(tái)線(xiàn)程,定時(shí)(300ms)輸出一段內(nèi)容,但不希望它一直運(yùn)行,所以設(shè)置了超時(shí)時(shí)間(3s),希望在超時(shí)結(jié)束后,便執(zhí)行后續(xù)的內(nèi)容。
根據(jù)需求,開(kāi)發(fā)了第一個(gè)版本的代碼,步驟如下:
定義一個(gè)Task。
在Task內(nèi),運(yùn)行死循環(huán),每間隔300毫秒,輸出一段內(nèi)容。
設(shè)置Task的等待超時(shí)時(shí)間,超時(shí)結(jié)束后,運(yùn)行后續(xù)內(nèi)容。
具體代碼如下所示:
namespace DemoTask { internal class Program { static void Main(string[] args) { TestTask(); Console.ReadKey(); } /// <summary> /// 測(cè)試任務(wù) /// </summary> public static void TestTask() { Console.WriteLine("程序開(kāi)始."); var task = Task.Run(() => { while (true) { Console.WriteLine($"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}程序正在運(yùn)行..."); Thread.Sleep(300); } }); task.Wait(3000); Console.WriteLine("程序超時(shí)結(jié)束."); } } }
信心滿(mǎn)滿(mǎn)的運(yùn)行程序,但是期待的結(jié)果并沒(méi)有出現(xiàn),在超時(shí)時(shí)間后,并沒(méi)有預(yù)期的停止任務(wù),反而在繼續(xù)運(yùn)行。如下所示:
注意:通過(guò)以上程序發(fā)現(xiàn),Wait方法只是等待時(shí)間結(jié)束后不再等待,但是原有任務(wù)并未結(jié)束,而是繼續(xù)運(yùn)行。
為了解決線(xiàn)程無(wú)法結(jié)束的問(wèn)題,微軟官方給出的方案是采用CancellationTokenSource,向應(yīng)該被取消的線(xiàn)程發(fā)送信號(hào)。即在線(xiàn)程內(nèi)部判斷是否收到取消請(qǐng)求,在外部發(fā)起取消請(qǐng)求信號(hào)。步驟如下:
定義一個(gè)Task。
在Task內(nèi),當(dāng)沒(méi)有收到取消信號(hào)時(shí),每間隔300毫秒,輸出一段內(nèi)容。
設(shè)置Task的等待超時(shí)時(shí)間,超時(shí)結(jié)束后,發(fā)起取消信號(hào),并運(yùn)行后續(xù)內(nèi)容。
具體代碼如下所示:
/// <summary> /// 測(cè)試任務(wù) /// </summary> public static void TestTask() { Console.WriteLine("程序開(kāi)始."); CancellationTokenSource cts = new CancellationTokenSource(); CancellationToken token = cts.Token; var task = Task.Run(() => { while (!token.IsCancellationRequested) { Console.WriteLine($"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}程序正在運(yùn)行..."); Thread.Sleep(300); } }); bool flag = task.Wait(3000); if (!flag) { cts.Cancel(); } Console.WriteLine("程序超時(shí)結(jié)束."); }
優(yōu)化程序后,運(yùn)行程序如下所示:
注意:經(jīng)過(guò)以上程序優(yōu)化后,確實(shí)是如預(yù)想的結(jié)果一致,程序在等待超時(shí)時(shí)間后,停止了運(yùn)行。
正常情況下,如果是我們自己開(kāi)發(fā)的程序,程序到第二個(gè)版本就已經(jīng)解決問(wèn)題了,但是假如While循環(huán)的內(nèi)容是第三方提供的程序,已經(jīng)封裝為固定模塊,我們無(wú)法進(jìn)行修改,那應(yīng)該如何才能終止死循環(huán)呢?如何才能像任務(wù)管理器結(jié)束進(jìn)程一樣,結(jié)束這一直無(wú)休止運(yùn)行的程序呢?
為了解決我們的難題,對(duì)程序進(jìn)行進(jìn)一步的優(yōu)化,步驟如下:
定義一個(gè)Task。
在Task內(nèi),注冊(cè)線(xiàn)程的Abort方法,在未調(diào)用Abort方法時(shí),每間隔300毫秒,輸出一段內(nèi)容。
設(shè)置Task的等待超時(shí)時(shí)間,超時(shí)結(jié)束后,發(fā)起取消信號(hào),并運(yùn)行后續(xù)內(nèi)容。
具體代碼如下所示:
/// <summary> /// 測(cè)試任務(wù) /// </summary> public static void TestTask() { Console.WriteLine("程序開(kāi)始."); CancellationTokenSource cts = new CancellationTokenSource(); CancellationToken token = cts.Token; var task = Task.Run(() => { using (token.Register((Thread.CurrentThread.Abort))) { //假設(shè)以下內(nèi)容第3方提供,無(wú)法修改 while (true) { Console.WriteLine($"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}程序正在運(yùn)行..."); Thread.Sleep(300); } //以上內(nèi)容第3方提供 } }); bool flag = task.Wait(3000); if (!flag) { cts.Cancel(); } Console.WriteLine("程序超時(shí)結(jié)束."); }
優(yōu)化程序后,運(yùn)行程序如下所示:
以上就是“C#怎么優(yōu)雅地終止線(xiàn)程”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家閱讀完這篇文章都有很大的收獲,小編每天都會(huì)為大家更新不同的知識(shí),如果還想學(xué)習(xí)更多的知識(shí),請(qǐng)關(guān)注億速云行業(yè)資訊頻道。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。