日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

多线程-Task、await/async

發布時間:2024/4/13 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 多线程-Task、await/async 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
Task創建無返回值

Task是.netframwork4.0重新分裝的多線程類。原因以前的多線程(thread threadpool)不好用。(.net framwork也是的發展的,現在的EF,剛開始是一個edmx文件,現在的code first,ef輕量級。但是其他有的技術也是死掉了)

Task具有線程執行的可控性,返回值,代碼書寫簡單,性能好等特點。

Task創建主要有三種方式

1、Task參數

Task t = new Task(() => {for (int i = 0; i < 10; i++){Console.WriteLine(i);} }); t.Start(); View Code

Action,Action<object>,object?state,CancellationToken,TaskCreationOptions

Action<object>:task創建有參數的任務,參數只能是object

object:帶有參數委托的參數。

CancellationToken:線程取消通知

TaskCreationOptions:控制Task的執行方式

// // 摘要: // 指定可控制任務的創建和執行的可選行為的標志。 [Flags] public enum TaskCreationOptions {//// 摘要:// 指定應使用默認行為。None = 0,//// 摘要:// 提示 System.Threading.Tasks.TaskScheduler 以一種盡可能公平的方式安排任務,這意味著較早安排的任務將更可能較早運行,而較晚安排運行的任務將更可能較晚運行。PreferFairness = 1,//// 摘要:// 指定任務將是長時間運行的、粗粒度的操作,涉及比細化的系統更少、更大的組件。它會向 System.Threading.Tasks.TaskScheduler// 提示,過度訂閱可能是合理的。您可以通過過度訂閱創建比可用硬件線程數更多的線程。LongRunning = 2,//// 摘要:// 指定將任務附加到任務層次結構中的某個父級。有關詳細信息,請參閱 已附加和已分離的子任務。AttachedToParent = 4,//// 摘要:// 如果嘗試附有子任務到創建的任務,指定 System.InvalidOperationException 將被引發。DenyChildAttach = 8,//// 摘要:// 防止環境計劃程序被視為已創建任務的當前計劃程序。這意味著像 StartNew 或 ContinueWith 創建任務的執行操作將被視為 System.Threading.Tasks.TaskScheduler.Default// 當前計劃程序。HideScheduler = 16 } View Code

2、Task.Factory.StartNew

Action,Action<object>,object state,CancellationToken,TaskCreationOptions,TaskScheduler

TaskScheduler:定義:用于計劃所創建的 System.Threading.Tasks.Task 的 System.Threading.Tasks.TaskScheduler。(并看不出來是什么意思,英文意思 任務調度器)

返回值是一個Task

Task.Factory.StartNew(() => {for (int i = 10; i < 20; i++){Console.WriteLine(i);} }); View Code

3、TaskFactory

Task.Factory是TaskFactory的一個實例。

TaskFactory tf = new TaskFactory(); tf.StartNew(() => {for (int i = 20; i < 30; i++){Console.WriteLine(i);} }); View Code

?上面的都是不帶返回參數的任務

Task創建有返回值

一般項目中的返回類型都會特定的封裝一個通用的類型。所有都會有返回值。

Task<string> t = new Task<string>(GetName); t.Start(); Console.WriteLine(t.Result); Console.WriteLine("結束"); View Code public static string GetName() {for (int i = 0; i < 10; i++){Console.WriteLine(i);}return "臧峰"; } View Code

注意在獲取返回值的時候,t.Result會卡著線程,一只等待線程返回結果。

Task等待

1、為什么要等待呢,因為線程大部分都要計算已給結果,所以我們要等待這個結果。

2、public void Wait(。。。。);

位于Task類中(實例方法。另外還有幾個靜態方法)。

定義:等待 System.Threading.Tasks.Task 完成執行過程(卡著其他線程)。

參數可以設置等待時間,CancellationToken(任務取消) ?等待期間可以取消任務。

3、public static void WaitAll(params Task[] tasks....);

定義:等待提供的所有 System.Threading.Tasks.Task 對象完成執行過程。(就是當前線程要等這個參數列表中線程全部執行完后 ?才執行。注意:waitall前面其他的子線程還是在繼續執行)

參數:等待任務列表,事件,CancellationToken

4、public static int WaitAny(params Task[] tasks);

定義:等待提供的任一 System.Threading.Tasks.Task 對象完成執行過程。

參數:等待任務列表,事件,CancellationToken

5、Task的屬性方法

AsyncState就是當任務核心方法帶參數的時候,參數值
Status任務執行進度的狀態
CreationOptions任務創建和執行的行為
Id任務線程ID
IsCanceled任務是否被取消
IsCompleted任務是否完成
IsFaulted任務是否失敗
Result任務返回值,該值只適用于有返回參數的任務

?

?

?

?

?

?

ContinueWith()線程執行完之后執行另外一個任務
GetAwaiter()獲取等待這個線程的等待著
Start()發起一個任務
Wait()當前調用wait的任務線程等待

?

?

?

這些是常用的

?

?

Task回調 //------------------------Task回調------------------------- Task<int> t = new Task<int>(() => {var temp = 0;for (int i = 0; i < 10; i++){temp += i;}return temp; });t.ContinueWith<string>((f) => {Console.WriteLine(f.Result.ToString());return f.Result.ToString(); }); t.Start();//------------------TaskFactory回調---------------------------- TaskFactory<int> tf = new TaskFactory<int>(); var tft = tf.StartNew(() =>{var temp = 0;for (int i = 0; i < 10; i++){temp += i;}return temp;}); tft.ContinueWith<string>((f) => {Console.WriteLine(f.Result.ToString());return f.Result.ToString(); });//-----------------------ContinueWhenAll-------------------------- var cts = new CancellationTokenSource(); TaskFactory<int> tf1 = new TaskFactory<int>(cts.Token, TaskCreationOptions.AttachedToParent, TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Default);Task<int> t1 = tf1.StartNew(() => { Console.WriteLine(1); return 1; }); Task<int> t2 = tf1.StartNew(() => { Console.WriteLine(2); return 2; }); Task<int> t3 = tf1.StartNew(() => { Console.WriteLine(3); return 3; }); Task<int> t4 = tf1.StartNew(() => { Console.WriteLine(4); return 4; }); Task<int> t5 = tf1.StartNew(() => { Console.WriteLine(5); return 5; });//意思就是說當這些所有的線程都執行完了,在執行后面的線程 //第一個參數就是要執行的線程數組 //第二個參數就是 繼續執行的線程 var tcwa = tf1.ContinueWhenAll(new[] { t1, t2, t3, t4, t5 }, tlReturn =>{int temp = 0;for (int i = 0; i < tlReturn.Length; i++){temp += tlReturn[i].Result;}Console.WriteLine(temp);return temp;});var tft1 = tf1.StartNew(() => {var temp = 0;for (int i = 0; i < 10; i++){temp += i;}Console.WriteLine(temp);return temp; });//-------------------------FromAsync----------------------------------- TaskFactory<long> tfFA = new TaskFactory<long>(); Func<long> faDel = (() => {Console.WriteLine("臧鋒");return 10; }); tfFA.FromAsync(faDel.BeginInvoke(null, null), (tr) => {Console.WriteLine(tr.IsCompleted);return 11; }); View Code

還是先了解一下TaskFactory

ContinueWhen不會卡當前線程。wait會卡當前線程。

CancellationToken任務取消標記
ContinuationOptions字面意思 任務延續選擇。官方注釋不敢恭維。和ContinueWhenAll、ContinueWhenAny有關
CreationOptions指定此任務工廠的默認創建選項。(任務執行順序,是否長時間執行...)
Scheduler任務工廠的任務計劃程序。表示一個處理將任務排隊到線程中的低級工作的對象。

?

?

?

?

?

ContinueWhenAll

創建一個延續任務,它將在提供的組中的所有任務完成后馬上開始。第一個參數P1:線程列表,就是要執行的線程

(必須有調用ContinueWhenAll的TaskFactory創建) ? ?第二個參數P2:回調函數

(回調函數的第一個參數為第一個參數P1,回調函數第二個參數為返回值,由TaskFactory<>定義的)。

? 執行順序 ?P1先執行,然后P2執行。 ? TaskFactory的任務為隨機執行

ContinueWhenAny創建一個延續任務,它將在提供的組中的任何任務完成后馬上開始。
FromAsync

創建一個任務,它在指定的 System.IAsyncResult 完成時執行一個結束方法函數。(官方解釋有點繞 ?其實就是

通過它可以把一個異步的任務轉換為一個Task,返回值是一個Task,最后在執行一個回調函數) ? ?

吐槽一下,官方的翻譯是不是都是電腦翻譯的。

StartNew創建開啟任務

?

Task取消

主要是類CancellationTokenSource

定義:通知 System.Threading.CancellationToken,告知其應被取消。

可以馬上取消,還可以設置時間取消。

CancellationTokenSource clt = new CancellationTokenSource(); TaskFactory tf = new TaskFactory(clt.Token); tf.StartNew(() => {int temp = 0;for (int i = 0; i < 10000; i++){Thread.Sleep(10);if (!clt.IsCancellationRequested){temp += i;}else{break;}}Console.WriteLine(temp); }); Thread.Sleep(200); clt.Cancel(); View Code Task返回值

具有返回值的是要用泛型 ?指定返回值類型。

Task<int> t = new Task<int>(() => 5); t.Start(); Console.WriteLine(t.Result);TaskFactory<int> tf = new TaskFactory<int>(); var tft= tf.StartNew(() => { return 6; }); Console.WriteLine(tft.Result); View Code

最后通過Task.Result得到結果。這個操作會卡著線程,一直等待回去結果。

?Parallel并行任務

1、Parallel ?定義:提供對并行循環和區域的支持。靜態類,靜態方法。他是基于Task,線程池。

其實是操作循環任務,但是循環的任務都是在平行執行的,沒人先后順序,但是,循環結會等待他們都結束的。

Parallel.For

Parallel.ForEach

Parallel.Invok

優點:主線程也會參與計算,缺點:就是會waitall ? 會卡住當前線程。

?

2、ParallelLoopResult 定義:提供執行 System.Threading.Tasks.Parallel 循環的完成狀態。其實就是For和ForEach的返回值

3、ParallelLoopState 定義:可用來使 System.Threading.Tasks.Parallel 循環的迭代與其他迭代交互。此類的實例由 Parallel 類提供給每個循環;不能在您的用戶代碼中創建實例。

他可以讓循環退出 ,通知。 ?(就像for循環中的bread)

4、ParallelOptions 定義:存儲用于配置 System.Threading.Tasks.Parallel 類的方法的操作的選項。

// // 摘要: // 獲取或設置與此 System.Threading.Tasks.ParallelOptions 實例關聯的 System.Threading.CancellationToken。 // // 返回結果: // 與此實例關聯的標記。 public CancellationToken CancellationToken { get; set; } // // 摘要: // 獲取或設置此 System.Threading.Tasks.ParallelOptions 實例所允許的最大并行度。 // // 返回結果: // 一個表示最大并行度的整數。 // // 異常: // T:System.ArgumentOutOfRangeException: // 該屬性被設置為 0 或小于 -1 的值。 public int MaxDegreeOfParallelism { get; set; } // // 摘要: // 獲取或設置與此 System.Threading.Tasks.ParallelOptions 實例關聯的 System.Threading.Tasks.TaskScheduler。將此屬性設置為 // null,以指示應使用當前計劃程序。 // // 返回結果: // 與此實例關聯的任務計劃程序。 public TaskScheduler TaskScheduler { get; set; } View Code

可以取消任務,并行的數量(循環中一次并行執行任務的個數,當任務量比較大的時候,一定要指定這個值,不然電腦可能撐不住。但是他是基于線程池的,線程池會幫我們控制一下,但是還是會卡電腦。并行數量控制,導致起的線程是一輪一輪的,每一輪第一個線程ID都一樣,用的主線程ID)

5、總結

?Parallel.For()和Paraller.ForEach()方法在每次迭代中調用相同的代碼,而Parallel.Invoke()方法允許同時調用不同的方法。Parallel.ForEach()用于數據并行性,Parallel.Invoke()用于任務并行性;

主線程可以參與計算,但是要waitall。等待。

Await Async

1、出現介紹

C#5.0 ? ? ? ? ? ? ? ? ?C#語言版本

.net fromwork 4.5 ? ? ? ? ? ? ? ?框架類庫版本FCL

clr4.0 ? ? ? ? ? ? ? ? ?CLR版本

await async他是一個語法糖。什么是語法糖呢,就是c#或者.net fromwork改變但是clr沒有改變。

泛型就不是語法糖,他出現的時候clr重寫了,就是使用泛型的地方, ?對應的生成相應的類型方法。

沒有task就沒有await async

2、原理

是一個語法糖,利用一個狀態機的概念,通過編譯器編譯把await后面的代碼封裝為一個委托進行回調執行,并且await會等待執行完成,狀態機就是這一個執行完之后,就movenest執行下一個回調。就是await一層層的嵌套就可以了。

3、使用

await只能出現在task前面,await后面的代碼變成task的回調。快速的寫出了異步回調

返回值只能是void task ?task<>,推薦使用task<>返回值,并封裝通用T類型。

?

本文代碼下載

補充例子

轉載于:https://www.cnblogs.com/wudequn/p/7571039.html

總結

以上是生活随笔為你收集整理的多线程-Task、await/async的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。