首頁>Club>
在C#中,開啟執行緒主要有Thread和Task兩種方法! 但是為什麼微軟會提供兩種方法呢? 兩種方法有啥區別?各有優劣?
171
回覆列表
  • 1 # 外老師

    Thread是C#中最早的多執行緒模型,後來才推出的Task。微軟推出Task的目的,就是要替代Thread,給程式設計師們提供一種更科學的執行緒模型。

    Thread

    Thread是基於delegate的早期執行緒模型。

    固定引數的delegate

    支援執行緒的常規操作,如Start,Join,Abort,Interrupt,Suspend,Resume等等。

    使用Thread可以完成大部分的常規執行緒操作。雖然Thread不如Task強大,但是Thread也有一個使用得非常廣泛的API:

    Thread.Sleep

    儘管設計得好的多執行緒程式,完全不需要顯式地Sleep!

    另外,剛才用.Net Framework 4.7.2 建立了一個專案,看了看Thred的API,居然也支援了Yield:

    Thread.Yield

    更有ResetAbort這種操作:

    Thread.ResetAbort

    真是不用Thread久已!

    Task

    Task是基於Action,Func的更加現代的執行緒模型。支援模板引數,比Thread中的固定引數delegate,在進行資料傳遞的時候,要更加靈活。

    基於Action

    Task採用了和ThreadPool類似的排程策略,但是Task在多核心CPU中在表現,要比ThreadPool更好。

    在單核心CPU上執行的時候,Thread和Task基本沒有太大區別。

    Task線上程的控制方面,有更加強大的API支援:

    Task透過CancellationToken支援一種執行緒的取消機制

    Task支援Delay操作

    Task提供了更完善的異常處理機制

    Task自帶執行緒工廠,方便隨時建立Task

    Task支援Wait WaitAny WaitAll

    Task支援WhenAny WhenAll

    Task支援ContinueWith,節省執行緒開銷

    Task支援Yield操作

    Task透過TaskScheduler可以支援執行緒佇列

    Task還可以配合 async 和 await 關鍵字,寫出更優雅的多執行緒程式,用過的人才知道有多香!

    。。。 。。。

    總之,Task是更加現代的執行緒管理模型,推薦優先使用Task。

    《C#中多執行緒的那點事兒-Thread入門》

    《C#中多執行緒的那點事-多執行緒的代價》

    《C#中多執行緒的那點事-執行緒池》

    《C#中多執行緒的那點事-鎖》

    《C#中多執行緒的那點事-死鎖》

    。。。。。。

  • 2 # 把嘴巴閉到起

    簡單的說thread更底層,用起來比較麻煩,容易出問題。

    task層次更高階,但底層還是thread,不讓你直接接觸thread了。

    推薦用task。

  • 3 # 創元科技公社

    簡單易懂!!看看就明白了

    1.什麼是thread

    當我們提及多執行緒的時候會想到thread和threadpool,這都是非同步操作,threadpool其實就是thread的集合,具有很多優勢,不過在任務多的時候全域性佇列會存在競爭而消耗資源。thread預設為前臺執行緒,主程式必須等執行緒跑完才會關閉,而threadpool相反。

    總結:threadpool確實比thread效能優,但是兩者都沒有很好的api區控制,如果執行緒執行無響應就只能等待結束,從而誕生了task任務。

    2.什麼是task

    task簡單地看就是任務,那和thread有什麼區別呢?Task的背後的實現也是使用了執行緒池執行緒,但它的效能優於ThreadPoll,因為它使用的不是執行緒池的全域性佇列,而是使用的本地佇列,使執行緒之間的資源競爭減少。同時Task提供了豐富的API來管理執行緒、控制。但是相對前面的兩種耗記憶體,Task依賴於CPU對於多核的CPU效能遠超前兩者,單核的CPU三者的效能沒什麼差別。

    Task其實就是在ThreadPool的基礎上進行一層封裝,ThreaPool啟動的執行緒不好判斷執行緒的執行情況,但Task可以,很好地解決了這個問題。

    Thread與ThreadPoll

    前臺執行緒:主程式必須等待執行緒執行完畢後才可退出程式。Thread預設為前臺執行緒,也可以設定為後臺執行緒

    後臺執行緒:主程式執行完畢後就退出,不管執行緒是否執行完畢。ThreadPool預設為後臺執行緒

    執行緒消耗:開啟一個新執行緒,執行緒不做任何操作,都要消耗1M左右的記憶體

    ThreadPoll是執行緒池 其目的是為了減少開啟新執行緒消耗的資源(使用執行緒池中的空閒執行緒,不必在開啟新執行緒,以及統一管理執行緒(執行緒池中的執行緒執行完畢後,迴歸到執行緒池裡,等待新任務).

    總結:ThreadPoll效能優於Thread,但是Thread和ThreadPoll對執行緒的控制都不是很好,例如執行緒等待(執行緒執行一段時間無響應後,直接停止執行緒,釋放資源 等 都沒有直接的API來控制 只能透過硬編碼來實現,同時ThreadPool使用的是執行緒池全域性佇列,全域性佇列中的執行緒依舊會存在競爭共享資源的情況,從而影響效能。

    然後task

    Task的背後的實現也是使用了執行緒池執行緒,但它的效能優於ThreadPoll,因為它使用的不是執行緒池的全域性佇列,而是使用的本地佇列,使執行緒之間的資源競爭減少。同時Task提供了豐富的API來管理執行緒、控制。但是相對前面的兩種耗記憶體,Task依賴於CPU對於多核的CPU效能遠超前兩者,單核的CPU三者的效能沒什麼差別。

    Task不等於Thread,只是微軟預設實現ThreadPoolTaskScheduler是依賴於執行緒池的,因為該類的可訪問性為internal,所以我們在實際編碼中無法直接在程式碼中new這麼一個Scheduler出來,只能透過TaskScheduler.Default間接的來使用

  • 中秋節和大豐收的關聯?
  • 有多少女人生完孩子後有離婚的想法?