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

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

這樣在 C# 使用 LongRunnigTask 是錯(cuò)的

2023-03-06 08:43 作者:Newbe36524  | 我要投稿

Task.Factory.StartNew 有一個(gè)重載,是支持 TaskCreationOptions.LongRunning 參數(shù)來指定 Task 的特征的。但是可能在沒有注意的情況下,你就使用了錯(cuò)誤的用法。那么本文我們來簡單闡述一下這個(gè)參數(shù)的作用,和使用的注意要點(diǎn)。

這樣其實(shí)是錯(cuò)誤的

有的時(shí)候,你可能會(huì)這么寫:

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

但其實(shí),這是個(gè)錯(cuò)誤的寫法。

為什么需要 LongRunning

我們通常兩種情況下會(huì)想到使用 TaskCreationOptions.LongRunning 參數(shù):

  1. 你的任務(wù)需要長時(shí)間運(yùn)行,比如一個(gè)循環(huán),或者一個(gè)死循環(huán)。用來從隊(duì)列中取數(shù)據(jù),然后處理數(shù)據(jù),或者是一些定時(shí)任務(wù)。

  2. 你的任務(wù)需要占用大量的 CPU 資源,是一個(gè)很大的循環(huán),比如要遍歷一個(gè)很大的數(shù)組,并做一些處理。

那么這個(gè)時(shí)候,我們就需要使用 TaskCreationOptions.LongRunning 參數(shù)來指定 Task。

因?yàn)槲覀兛赡軐W(xué)習(xí)到了,Task 默認(rèn)的 Scheduler 是 ThreadPool,而 ThreadPool 的線程是有限的,如果你的任務(wù)需要長時(shí)間運(yùn)行,或者是需要占用大量的 CPU 資源,那么就會(huì)導(dǎo)致 ThreadPool 的線程不夠用。導(dǎo)致線程饑餓,或者是線程池的線程被占用,導(dǎo)致其他的任務(wù)無法執(zhí)行。

于是我們很聰明的就想到了,我們可以使用 TaskCreationOptions.LongRunning 參數(shù)來指定 Task,這樣就可以避免線程饑餓。

弄巧成拙

但是實(shí)際上,開篇的寫法并不能達(dá)到我們的目的。

我們可以通過以下代碼來驗(yàn)證一下:

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

我們可以看到,Task 的狀態(tài)是并非是 Running,而是 RanToCompletion。

也就是說,我們的任務(wù)在 3 秒后就已經(jīng)執(zhí)行完了,而不是我們想要的長時(shí)間運(yùn)行。

究其原因,是因?yàn)槲覀儾捎昧水惒降姆绞絹韴?zhí)行任務(wù)。而異步任務(wù)的執(zhí)行,是通過 ThreadPool 來執(zhí)行的。也就是說,雖然我們使用了 TaskCreationOptions.LongRunning 參數(shù),來想辦法指定線程池單獨(dú)開一個(gè)線程,但是實(shí)際上在一個(gè) await 之后,我們的任務(wù)還是在 ThreadPool 中執(zhí)行的。

這會(huì)導(dǎo)致,我們的任務(wù)實(shí)際上后續(xù)又回到了 ThreadPool 中,而不是我們想要的單獨(dú)的線程。起不到單獨(dú)長期運(yùn)行的作用。

正確的寫法

因此,實(shí)際上如果想要保持單獨(dú)的線程持續(xù)的運(yùn)行,我們需要移除異步的方式,改為同步的方式。

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

這樣我們就可以看到,Task 的狀態(tài)是 Running,而不是 RanToCompletion。我們通過 TaskCreationOptions.LongRunning 參數(shù),單獨(dú)開啟的線程就可以一直運(yùn)行下去。

實(shí)際上還有很多考量

要考量 TaskScheduler 的實(shí)現(xiàn)

本文采用的是 aspnetcore 的實(shí)現(xiàn),但是在其他的實(shí)現(xiàn)中,可能會(huì)有不同的實(shí)現(xiàn)。你也完全有可能實(shí)現(xiàn)一個(gè) await 之后,不回到 ThreadPool 的實(shí)現(xiàn)。

LongRunning 也不是就不能用異步

正如開篇提到的第二種場景,如果你的業(yè)務(wù)是在第一個(gè) await 之前有大量的同步代碼,那么此時(shí)單獨(dú)開啟一個(gè)線程,也是有意義的。

我就是一個(gè)死循環(huán),里面也是異步的怎么辦

那么你可以考慮讓這個(gè) LongRuning 的 Task,不要 await,而是通過 Wait() 來等待。這樣就可以避免 LongRunning 的 Task 直接結(jié)束。

總結(jié)

本文我們簡單闡述了 TaskCreationOptions.LongRunning 參數(shù)的作用,和使用的注意要點(diǎn)。

參考

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

  • Task2

  • TaskCreationOptions3

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

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

  • 本文作者: newbe36524

  • 本文鏈接: https://www.newbe.pro/Others/0x026-This-is-the-wrong-way-to-use-LongRunnigTask-in-csharp/

  • 版權(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?


這樣在 C# 使用 LongRunnigTask 是錯(cuò)的的評(píng)論 (共 條)

分享到微博請(qǐng)遵守國家法律
财经| 桦南县| 思南县| 淅川县| 兖州市| 山西省| 梓潼县| 赤壁市| 东乡族自治县| 逊克县| 英德市| 乌苏市| 池州市| 揭西县| 青龙| 佛教| 辽宁省| 永泰县| 长岛县| 获嘉县| 新宁县| 陇西县| 红桥区| 旅游| 葵青区| 镇宁| 旬阳县| 蒲城县| 开化县| 瓦房店市| 康平县| 瑞金市| 准格尔旗| 恭城| 会东县| 鄢陵县| 江源县| 三江| 蓬安县| 富阳市| 庆城县|