五月天青色头像情侣网名,国产亚洲av片在线观看18女人,黑人巨茎大战俄罗斯美女,扒下她的小内裤打屁股

歡迎光臨散文網(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)遵守國家法律
乌审旗| 周口市| 南部县| 三原县| 广东省| 衡阳市| 江川县| 新河县| 巴楚县| 五大连池市| 海南省| 云浮市| 大新县| 精河县| 当涂县| 弋阳县| 成都市| 达州市| 姜堰市| 田阳县| 旌德县| 攀枝花市| 盐城市| 都兰县| 天峻县| 长泰县| 永德县| 郑州市| 柳江县| 灵台县| 隆昌县| 绍兴市| 云林县| 肇庆市| 新民市| 辽宁省| 都江堰市| 牡丹江市| 玉环县| 浮山县| 堆龙德庆县|