最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊(cè)

實(shí)現(xiàn)常駐任務(wù)除了避免曇花線(xiàn)程,還需要避免重返線(xiàn)程池

2023-03-20 08:39 作者:Newbe36524  | 我要投稿

前面我們使用簡(jiǎn)單的例子演示了 Task 和 Thread 的兩種制造曇花線(xiàn)程的方式。那么除了避免曇花線(xiàn)程,在實(shí)現(xiàn)常駐任務(wù)的時(shí)候,還需要避免重返線(xiàn)程池。本文將介紹如何避免重返線(xiàn)程池。

常駐任務(wù)

常駐任務(wù)非常常見(jiàn),比如:

  1. 我們正在編寫(xiě)一個(gè)日志文件庫(kù),我們希望在后臺(tái)不斷的將日志寫(xiě)入文件,盡可能不影響業(yè)務(wù)線(xiàn)程的執(zhí)行。因此,需要一個(gè)寫(xiě)文件的常駐任務(wù)。

  2. 我們對(duì)接了一個(gè)遠(yuǎn)程 TCP 服務(wù),對(duì)方要求我們每隔一段時(shí)間發(fā)送一個(gè)心跳包,以保持連接。因此,需要一個(gè)發(fā)送心跳包的常駐任務(wù)。

  3. 我們編寫(xiě)了一個(gè)簡(jiǎn)單的內(nèi)存緩存,通過(guò)一個(gè)后臺(tái)任務(wù)來(lái)定期清理過(guò)期的緩存。因此,需要一個(gè)清理緩存的常駐任務(wù)。

類(lèi)似的場(chǎng)景還有很多。因此,我們需要一個(gè)能夠?qū)崿F(xiàn)常駐任務(wù)的方法。

而實(shí)現(xiàn)常駐任務(wù)的主要要點(diǎn)是:

  1. 常駐任務(wù)必須避免影響業(yè)務(wù)線(xiàn)程的執(zhí)行,因此需要在后臺(tái)執(zhí)行。

  2. 常駐任務(wù)不能被業(yè)務(wù)線(xiàn)程影響,無(wú)論當(dāng)前業(yè)務(wù)多么繁忙,常駐任務(wù)都必須能夠正常執(zhí)行。否則會(huì)出現(xiàn)日志不落盤(pán),心跳包不發(fā)送,緩存不清理等問(wèn)題。

實(shí)現(xiàn)常駐任務(wù)的手段有很多。本文將圍繞如何使用常駐單一線(xiàn)程來(lái)實(shí)現(xiàn)常駐任務(wù)。

所謂常駐單一線(xiàn)程,就是指始終使用一個(gè)線(xiàn)程來(lái)執(zhí)行常駐任務(wù)。從而達(dá)到:

  1. 避免頻繁的創(chuàng)建和銷(xiāo)毀線(xiàn)程,從而避免頻繁的線(xiàn)程切換。

  2. 更容易的處理背壓?jiǎn)栴}。

  3. 更容易的處理線(xiàn)程安全問(wèn)題。

評(píng)測(cè)主體

我們將采用如下情況來(lái)評(píng)測(cè)如何編寫(xiě)常駐任務(wù)的正確性。

Bilibili 代碼塊無(wú)法正常渲染,因此無(wú)法正常顯示。請(qǐng)關(guān)注微信公眾號(hào)“newbe技術(shù)專(zhuān)欄”,搜索對(duì)應(yīng)文章代碼內(nèi)容。

這里我們定義了一個(gè) ProcessTest 方法,用于評(píng)測(cè)常駐任務(wù)的正確性。我們將在這個(gè)方法中啟動(dòng)常駐任務(wù),然后執(zhí)行一個(gè)嚴(yán)架給壓力的方法,來(lái)模擬非常繁忙的業(yè)務(wù)操作。最后我們將輸出常駐任務(wù)中的計(jì)數(shù)器的值。

可以初步看一下嚴(yán)架帶來(lái)的壓力有多大:

然后我們不妨假設(shè),我們的常駐任務(wù)是希望每秒進(jìn)行一次計(jì)數(shù)。那么最終在控制臺(tái)輸出的結(jié)果應(yīng)該是 5 或者 6。但如果小于 5,那么就說(shuō)明我們的常駐任務(wù)有問(wèn)題。

比如下面這樣:

Bilibili 代碼塊無(wú)法正常渲染,因此無(wú)法正常顯示。請(qǐng)關(guān)注微信公眾號(hào)“newbe技術(shù)專(zhuān)欄”,搜索對(duì)應(yīng)文章代碼內(nèi)容。

在該測(cè)試中,我們希望使用 Task.Run 來(lái)執(zhí)行我們期待的循環(huán),進(jìn)行每秒加一的操作。但是,我們發(fā)現(xiàn),最終輸出的結(jié)果是 1。這是因?yàn)椋?/p>

  1. Task.Run 會(huì)將我們的任務(wù)放入 Task Default Scheduler 線(xiàn)程池中執(zhí)行。

  2. 但是由于迫于嚴(yán)架給壓力,我們的業(yè)務(wù)線(xiàn)程會(huì)一直處于繁忙狀態(tài),因此線(xiàn)程池中的線(xiàn)程也會(huì)一直處于繁忙狀態(tài)。

  3. 從而日導(dǎo)致我們的常駐任務(wù)無(wú)法正常執(zhí)行。

這里我們可以看到,Task.Run 并不是一種正確的實(shí)現(xiàn)常駐任務(wù)的方法。當(dāng)然實(shí)際上這也不是常駐單一線(xiàn)程,因?yàn)檫@樣本質(zhì)是使用了線(xiàn)程池。

歡迎關(guān)注作者的微信公眾號(hào)“newbe技術(shù)專(zhuān)欄”,獲取更多技術(shù)內(nèi)容。

全同步過(guò)程

結(jié)合我們之前提到的 TaskCreationOptions.LongRunning 以及 Thread 很容易在全同步的情況下實(shí)現(xiàn)常駐單一線(xiàn)程。

Bilibili 代碼塊無(wú)法正常渲染,因此無(wú)法正常顯示。請(qǐng)關(guān)注微信公眾號(hào)“newbe技術(shù)專(zhuān)欄”,搜索對(duì)應(yīng)文章代碼內(nèi)容。

這兩種正確的寫(xiě)法都實(shí)現(xiàn)了常駐單一線(xiàn)程,因此我們可以看到,最終輸出的結(jié)果都是 6。

曇花線(xiàn)程

那么自然,我們也可以知道,如果混合了曇花線(xiàn)程,那么就會(huì)出現(xiàn)問(wèn)題。

Bilibili 代碼塊無(wú)法正常渲染,因此無(wú)法正常顯示。請(qǐng)關(guān)注微信公眾號(hào)“newbe技術(shù)專(zhuān)欄”,搜索對(duì)應(yīng)文章代碼內(nèi)容。

這兩種錯(cuò)誤的寫(xiě)法都無(wú)法實(shí)現(xiàn)常駐單一線(xiàn)程,因此我們可以看到,最終輸出的結(jié)果都是 1。

不是有 Task 就是異步的

雖然不是本篇的關(guān)鍵內(nèi)容,但是還是額外補(bǔ)充兩個(gè) case 作為對(duì)比:

Bilibili 代碼塊無(wú)法正常渲染,因此無(wú)法正常顯示。請(qǐng)關(guān)注微信公眾號(hào)“newbe技術(shù)專(zhuān)欄”,搜索對(duì)應(yīng)文章代碼內(nèi)容。

在這兩個(gè) case 但中,雖然在 while 中包含了 wait Task,但是由于 Task.CompletedTask 實(shí)際上是一種同步代碼,所以并不會(huì)進(jìn)入到線(xiàn)程池當(dāng)中。因此也就不會(huì)出現(xiàn)錯(cuò)誤的情況。

但是這種錯(cuò)誤的原因不是因?yàn)闀一ň€(xiàn)程,是由于我們?cè)?Thread 中進(jìn)行了 Wait,但是被調(diào)用的 Task 如果確實(shí)是一個(gè)異步的 Task,那么由于線(xiàn)程池繁忙,我們的 Task 就會(huì)被延遲執(zhí)行,因此就會(huì)出現(xiàn)錯(cuò)誤的情況。

總結(jié)

  1. 在全同步的情況下,我們可以使用 TaskCreationOptions.LongRunning 或者 Thread 來(lái)實(shí)現(xiàn)常駐單一線(xiàn)程。從而實(shí)現(xiàn)穩(wěn)定的常駐任務(wù)。

  2. 注意 async/await 可能會(huì)導(dǎo)致線(xiàn)程池的使用,從而避免常駐單一線(xiàn)程被破壞。

  3. 我們暫未給出帶有異步代碼的情況下如何實(shí)現(xiàn)穩(wěn)定的常駐任務(wù),我們將在后續(xù)討論。

測(cè)試代碼:https://github.com/newbe36524/Newbe.Demo/tree/main/src/BlogDemos/Newbe.LongRunningJob

參考

  • .NET Task 揭秘(2):Task 的回調(diào)執(zhí)行與 await1

  • Task2

  • TaskCreationOptions3

  • 這樣在 C# 使用 LongRunningTask 是錯(cuò)的4

  • async 與 Thread 的錯(cuò)誤結(jié)合5

感謝您的閱讀,如果您覺(jué)得本文有用,快長(zhǎng)按右下角大拇指??為本文點(diǎn)贊~

歡迎關(guān)注作者的微信公眾號(hào)“newbe技術(shù)專(zhuān)欄”,獲取更多技術(shù)內(nèi)容。

  • 本文作者: newbe36524

  • 本文鏈接: https://www.newbe.pro/Others/0x028-avoid-return-to-threadpool-in-longrunning-task/

  • 版權(quán)聲明: 本博客所有文章除特別聲明外,均采用 BY-NC-SA 許可協(xié)議。轉(zhuǎn)載請(qǐng)注明出處!

  1. https://www.cnblogs.com/eventhorizon/p/15912383.html?

  2. https://threads.whuanle.cn/3.task/?

  3. https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.taskcreationoptions?view=net-7.0&WT.mc_id=DX-MVP-5003606?

  4. https://www.newbe.pro/Others/0x026-This-is-the-wrong-way-to-use-LongRunnigTask-in-csharp/?

  5. https://www.newbe.pro/Others/0x027-error-when-using-async-with-thread/?


實(shí)現(xiàn)常駐任務(wù)除了避免曇花線(xiàn)程,還需要避免重返線(xiàn)程池的評(píng)論 (共 條)

分享到微博請(qǐng)遵守國(guó)家法律
大关县| 资兴市| 肥东县| 南宁市| 南郑县| 泰安市| 广东省| 威宁| 连州市| 梓潼县| 西乡县| 乌兰察布市| 宁陕县| 镇平县| 建始县| 兴山县| 太康县| 长葛市| 临朐县| 荃湾区| 涪陵区| 新疆| 八宿县| 宜宾县| 邹平县| 江山市| 彝良县| 沈丘县| 平度市| 噶尔县| 衡南县| 宜阳县| 葵青区| 丰镇市| 罗平县| 吉安县| 南丹县| 桦川县| 修水县| 鹿邑县| 库伦旗|