你想象中的Task后续,很简单?
【導讀】前不久,寫過一篇關于Task的簡短文章,通過評論和轉載得到好評,剛好我昨晚又寫了一篇實現簡單的消息隊列也提到了Task,難道不應該是看具體執行什么操作,再考慮最佳方案?本文我們再次通過簡短內容談談Task
在評論中我提到,Task默認在線程池中運行,若執行耗時操作,此時極容易造成線程阻塞,最終導致線程池激增,很顯然這是不正確的做法
然鵝,有的童鞋說了,給Task配置TaskCreationOptions.LongRunning即可解決耗時問題,此時將創建線程而非在線程池運行,要是執行耗時操作且無需知道返回結果(見上一篇),那干嘛不直接用Thread呢?
TaskCreationOptions.LongRunning直接創建線程,所以本文我們重點來講講該選項的正確使用方式,知其然,知其所以然。
再談Task創建線程
我們一直在強調配置Task選項即可創建非線程池線程,那么我們是否可以通過一個簡單例子來進行一次論證呢?如下代碼和圖展足以勝前言,至于細節,只能自行研究源碼得知
證明:TaskCreationOptions.LongRunning創建非線程池線程
public?static?Format?_colorify?{?get;?set;?} static?void?Main(string[]?args) {_colorify?=?new?Format(Theme.Light);int?workerThreads,?completionPortThreads;ThreadPool.GetMaxThreads(out?workerThreads,?out?completionPortThreads);_colorify.WriteLine(workerThreads.ToString(),?Colors.bgDefault);_colorify.WriteLine(completionPortThreads.ToString(),?Colors.bgDefault);ThreadPool.GetAvailableThreads(out?workerThreads,?out?completionPortThreads);_colorify.WriteLine(workerThreads.ToString(),?Colors.bgDefault);_colorify.WriteLine(completionPortThreads.ToString(),?Colors.bgDefault);_colorify.WriteLine("---------------------------",?Colors.bgSuccess);Task.Factory.StartNew(()?=>{ThreadPool.GetMaxThreads(out?workerThreads,?out?completionPortThreads);_colorify.WriteLine(workerThreads.ToString(),?Colors.bgWarning);_colorify.WriteLine(completionPortThreads.ToString(),?Colors.bgWarning);ThreadPool.GetAvailableThreads(out?workerThreads,?out?completionPortThreads);_colorify.WriteLine(workerThreads.ToString(),?Colors.bgWarning);_colorify.WriteLine(completionPortThreads.ToString(),?Colors.bgWarning);},?TaskCreationOptions.LongRunning);Console.Read(); }同樣,反其道行之,將LongRunning選項配置去除,則如下橙色部分所展示的線程池工作線程將減少1即(32766)
Task配置LongRunning是否可用于異步呢?
針對此問題的答案,如果我們不能立馬給出答案,那么說明我們對異步還沒有充分的理解,這里給出我對異步淺薄的定義:添加必要的邏輯(狀態機),以允許釋放當前線程,若長時間運行的異步操作已完成,則將結果返回到同一線程中,換言之,異步僅用于I/O操作。
我們來看如下一個例子
static?async?Task?Main(string[]?args) {await?AsyncTaskFactoryNew();Console.Read(); }static?async?Task?AsyncTaskFactoryNew() {await?Task.Factory.StartNew(()?=>?{//?do?your?logic}); }
通過上述我們對異步的定義,然后再來看上述例子,結果顯而易見,因為用了異步后將釋放當前線程,也就是在第一次await后,通過Task選項所配置的創建非線程池線程將會被銷毀,所以給Task配置創建非線程池線程結合使用異步相互矛盾,故毫無意義。
幾篇簡短內容,仍只是冰山一角,其中所涉及內容仍有許多供我們好好研究,比如如何利用Task實現斷點續傳中的暫停、取消呢?
總結
以上是生活随笔為你收集整理的你想象中的Task后续,很简单?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 源码都没调试过,怎么能说熟悉 redis
- 下一篇: 5G在工业互联网应用的机遇与挑战