///Task簡(jiǎn)單使用///privatevoidDemo1(){inti=0;Randomr=newRandom(DateTime.Now.Seco" />

日韩久久久精品,亚洲精品久久久久久久久久久,亚洲欧美一区二区三区国产精品 ,一区二区福利

4.0中的并行計(jì)算和多線程詳解(二)

系統(tǒng) 2034 0

多線程部分

多線程在4.0中被簡(jiǎn)化了很多,僅僅只需要用到System.Threading.Tasks.::.Task類(lèi),下面就來(lái)詳細(xì)介紹下Task類(lèi)的使用。

一、簡(jiǎn)單使用

開(kāi)啟一個(gè)線程,執(zhí)行循環(huán)方法,返回結(jié)果。開(kāi)始線程為Start(),等待線程結(jié)束為Wait()。

Code
  1. ??????? /// <summary>
  2. ??????? /// Task簡(jiǎn)單使用
  3. ??????? /// </summary>
  4. ??????? private void Demo1()
  5. ??????? {
  6. ??????????? int i = 0;
  7. ??????????? Random r = new Random ( DateTime .Now.Second);
  8. ??????????? Task t = new Task (() =>
  9. ??????????? {
  10. ??????????????? for ( int v = 0; v < 100; v++)
  11. ??????????????????? i += r.Next(100);
  12. ??????????? });
  13. ??????????? t.Start();
  14. ??????????? t.Wait();
  15. ??????????? Console .WriteLine( "這是執(zhí)行Task1后等待完成:" + i.ToString());
  16. ??????????? Console .ReadLine();
  17. ??????? }

比以前使用Thread方便多了吧。

上面的例子是使用外部的變量獲得結(jié)果,下面的例子是用Task<T>直接返回結(jié)果,當(dāng)調(diào)用Result屬性時(shí),會(huì)自動(dòng)等待線程結(jié)束,等同調(diào)用了Wait()。代碼如下:

Code
  1. ??????? /// <summary>
  2. ??????? /// Task帶返回值
  3. ??????? /// </summary>
  4. ??????? private void Demo2()
  5. ??????? {
  6. ??????????? Random r = new Random ( DateTime .Now.Second);
  7. ??????????? Task < int > t = new Task < int >(() =>
  8. ??????????? {
  9. ??????????????? int i = 0;
  10. ??????????????? for ( int v = 0; v < 100; v++)
  11. ??????????????????? i += r.Next(100);
  12. ??????????????? return i;
  13. ??????????? });
  14. ??????????? t.Start();
  15. ??????????? Console .WriteLine( "這是執(zhí)行Task1獲取返回值:" + t.Result.ToString());
  16. ??????????? Console .ReadLine();
  17. ??????? }

總結(jié)1:Task的使用比Thread簡(jiǎn)單很多,減少了同步,等待等等問(wèn)題,唯一的遺憾是不支持Thread的IsBackground。

結(jié)論1:如果不需要使用IsBackground,那么盡情的使用Task吧。

?

?

二、線程執(zhí)行完畢后調(diào)用另一個(gè)線程

也就是兩個(gè)線程,有序的執(zhí)行,這里使用ContinueWith(),

t執(zhí)行完畢后再執(zhí)行一個(gè)task方法,不多說(shuō)了代碼如下:

Code
  1. ??????? /// <summary>
  2. ??????? /// Task 執(zhí)行完畢后調(diào)用另一個(gè)Task
  3. ??????? /// </summary>
  4. ??????? private void Demo3()
  5. ??????? {
  6. ??????????? Random r = new Random ( DateTime .Now.Second);
  7. ??????????? Task < int > t = new Task < int >(() =>
  8. ??????????? {
  9. ??????????????? int i = 0;
  10. ??????????????? for ( int v = 0; v < 100; v++)
  11. ??????????????????? i += r.Next(100);
  12. ??????????????? return i;
  13. ??????????? });
  14. ??????????? t.ContinueWith(( Task < int > task) =>
  15. ??????????? {
  16. ??????????????? Console .WriteLine( "這是執(zhí)行完畢Task1后繼續(xù)調(diào)用Task2:" + task.Result.ToString());
  17. ??????????? });
  18. ??????????? t.Start();
  19. ??????????? Console .ReadLine();
  20. ??????? }

也可以直接鏈?zhǔn)降膶?xiě)下去,代碼如下:

Code
  1. ??????? /// <summary>
  2. ??????? /// Task 執(zhí)行完畢后調(diào)用另一個(gè)Task(鏈?zhǔn)綄?xiě)法)
  3. ??????? /// </summary>
  4. ??????? private void Demo4()
  5. ??????? {
  6. ??????????? Random r = new Random ( DateTime .Now.Second);
  7. ??????????? Task < int > t = new Task < int >(() =>
  8. ??????????? {
  9. ??????????????? int i = 0;
  10. ??????????????? for ( int v = 0; v < 100; v++)
  11. ??????????????????? i += r.Next(100);
  12. ??????????????? return i;
  13. ??????????? });
  14. ??????????? Task t2 = t.ContinueWith(( Task < int > task) =>
  15. ??????????? {
  16. ??????????????? Console .WriteLine(task.Result.ToString());
  17. ??????????? });
  18. ??????????? t2.ContinueWith(task =>
  19. ??????????? {
  20. ??????????????? Console .WriteLine( "這是執(zhí)行完畢Task1后繼續(xù)調(diào)用Task2,Task2后調(diào)用Task3。" );
  21. ??????????? });
  22. ??????????? t.Start();
  23. ??????????? Console .ReadLine();
  24. ??????? }

結(jié)論2:Task可以便捷的將幾個(gè)方法串行執(zhí)行。

?

?

三、帶有父子關(guān)系的線程/多線程并行開(kāi)啟

t帶有t1,t2,t3三個(gè)子線程,執(zhí)行t的時(shí)候t1,t2,t3可并行處理,t必須等待t1,t2,t3都執(zhí)行完畢后才能結(jié)束。

創(chuàng)建子Task時(shí)候必須指定參數(shù)為AttachedToParent。

Code
  1. ??????? /// <summary>
  2. ??????? /// 帶有父子關(guān)系的Task集合,[TaskCreationOptions.AttachedToParent]
  3. ??????? ///
  4. ??????? /// 值??????????????? 說(shuō)明
  5. ??????? /// None????????????? 默認(rèn)值,此Task會(huì)被排入Local Queue中等待執(zhí)行,采用LIFO模式。
  6. ??????? /// AttachedToParent? 建立的Task必須是外圍的Task的子Task,也是放入Local Queue,採(cǎi)LIFO模式。
  7. ??????? /// LongRunning?????? 建立的Task不受Thread Pool所管理,直接新增一個(gè)Thread來(lái)執(zhí)行此Task,無(wú)等待、無(wú)排程。
  8. ??????? /// PreferFairness??? 建立的Task直接放入Global Queue中,採(cǎi)FIFO模式。(比上面的優(yōu)先級(jí)低)
  9. ??????? /// </summary>
  10. ??????? private void Demo5()
  11. ??????? {
  12. ??????????? Task < int > t = new Task < int >(() =>
  13. ??????????? {
  14. ??????????????? Task < int > t1 = new Task < int >(() =>
  15. ??????????????? {
  16. ??????????????????? int i = 0;
  17. ??????????????????? Random r = new Random ( DateTime .Now.Second);
  18. ??????????????????? for ( int v = 0; v < 100; v++)
  19. ??????????????????????? i += r.Next(100);
  20. ??????????????????? return i;
  21. ??????????????? }, TaskCreationOptions .AttachedToParent);
  22. ??????????????? Task < int > t2 = new Task < int >(() =>
  23. ??????????????? {
  24. ??????????????????? int i = 0;
  25. ??????????????????? Random r = new Random ( DateTime .Now.Second);
  26. ??????????????????? for ( int v = 0; v < 100; v++)
  27. ??????????????????????? i += r.Next(100);
  28. ??????????????????? return i;
  29. ??????????????? }, TaskCreationOptions .AttachedToParent);
  30. ??????????????? Task < int > t3 = new Task < int >(() =>
  31. ??????????????? {
  32. ??????????????????? int i = 0;
  33. ??????????????????? Random r = new Random ( DateTime .Now.Second);
  34. ??????????????????? for ( int v = 0; v < 100; v++)
  35. ??????????????????????? i += r.Next(100);
  36. ??????????????????? return i;
  37. ??????????????? }, TaskCreationOptions .AttachedToParent);
  38. ??????????????? t1.Start();
  39. ??????????????? t2.Start();
  40. ??????????????? t3.Start();
  41. ??????????????? return t1.Result + t2.Result + t3.Result;
  42. ??????????? });
  43. ??????????? t.Start();
  44. ??????????? t.Wait();
  45. ??????????? Console .WriteLine( "這是帶有父子關(guān)系的Task集合:" + t.Result.ToString());
  46. ??????????? Console .ReadLine();
  47. ??????? }

結(jié)論3:多個(gè)線程的同時(shí)開(kāi)啟在這里也很方便,也不用擔(dān)心同步等問(wèn)題。

?

?

四、Task的中斷

這個(gè)很復(fù)雜,就不多說(shuō)了,代碼中有比較詳細(xì)的介紹。

Code
  1. ??????? /// <summary>
  2. ??????? /// 中途取消Task執(zhí)行,Token
  3. ??????? ///
  4. ??????? /// 一是正常結(jié)束、二是產(chǎn)生例外、三是透過(guò)Cancel機(jī)制,這三種情況都會(huì)反映在Task.Status屬性上
  5. ??????? /// 值????????????????????????????? 說(shuō)明
  6. ??????? /// Created???????????????????????? Task已經(jīng)建立,但未呼叫Start。
  7. ??????? /// WaitingForActivation??????????? Task已排入排程,但尚未執(zhí)行(一般我們建立的Task不會(huì)有此狀態(tài),只有ContinueWith所產(chǎn)生的Task才會(huì)有此狀態(tài))。
  8. ??????? /// WaitingToRun??????????????????? Task已排入排程,等待執(zhí)行中。
  9. ??????? /// Running???????????????????????? Task執(zhí)行中。
  10. ??????? /// WaitingForChildrenToComplete??? Task正等待子Task結(jié)束。
  11. ??????? /// RanToCompletion???????????????? Task已經(jīng)正常執(zhí)行完畢。
  12. ??????? /// Canceled??????????????????????? Task已被取消。
  13. ??????? /// Faulted???????????????????????? Task執(zhí)行中發(fā)生未預(yù)期例外。
  14. ??????? ///
  15. ??????? /// 除了Status屬性外,Task還提供了另外三個(gè)屬性來(lái)判定Task狀態(tài)。
  16. ??????? /// 屬性??????????? 說(shuō)明
  17. ??????? /// IsCompleted???? Task已經(jīng)正常執(zhí)行完畢。
  18. ??????? /// IsFaulted?????? Task執(zhí)行中法生未預(yù)期例外。
  19. ??????? /// IsCanceled????? Task已被取消。
  20. ??????? /// </summary>
  21. ??????? private void Demo6()
  22. ??????? {
  23. ??????????? CancellationTokenSource cts = new CancellationTokenSource ();
  24. ??????????? var ctoken = cts.Token;
  25. ??????????? Task t1 = new Task (() =>
  26. ??????????? {
  27. ??????????????? for ( int v = 0; v < 10; v++)
  28. ??????????????? {
  29. ??????????????????? if (ctoken.IsCancellationRequested)
  30. ??????????????????? {
  31. ??????????????????????? //第一種寫(xiě)法
  32. ??????????????????????? //這個(gè)會(huì)拋出異常
  33. ??????????????????????? ctoken.ThrowIfCancellationRequested();
  34. ??????????????????????? //另一種寫(xiě)法
  35. ??????????????????????? //這個(gè)不會(huì)返回異常,但是獲取不到是否是中斷還是執(zhí)行完畢。
  36. ??????????????????????? //return;
  37. ??????????????????? }
  38. ??????????????????? Thread .Sleep(1000);
  39. ??????????????????? Console .WriteLine(v);
  40. ??????????????? }
  41. ??????????? }, ctoken);
  42. ??????????? t1.Start();
  43. ??????????? Thread .Sleep(2000);
  44. ??????????? cts.Cancel();
  45. ??????????? try
  46. ??????????? {
  47. ??????????????? t1.Wait();
  48. ??????????? }
  49. ??????????? catch
  50. ??????????? {
  51. ??????????????? if (t1.IsCanceled)
  52. ??????????????????? Console .WriteLine( "cancel" );
  53. ??????????? }
  54. ??????????? Console .ReadLine();
  55. ??????????? cts.Dispose();
  56. ??????? }

結(jié)論4:中斷很復(fù)雜,但是對(duì)一般邏輯來(lái)說(shuō),是沒(méi)有很大必要的。

?

?

五、其他

這里介紹下另一種寫(xiě)法Task.Factory,以及ContinueWhenAny和ContinueWhenAll兩個(gè)方法。

Task.Factory是靜態(tài)工廠類(lèi),用于對(duì)Task提供一些麻煩的支持,這里主要介紹ContinueWhenAny和ContinueWhenAll。

ContinueWhenAll所指定的函式會(huì)在傳入的所有Tasks結(jié)束時(shí)執(zhí)行,只會(huì)執(zhí)行一次。

ContinueWhenAny所指定的函式會(huì)在傳入的Tasks中有任何一個(gè)結(jié)束時(shí)執(zhí)行,且與ContinueWhenAll相同,只會(huì)執(zhí)行一次。

好了,還是看代碼:

Code
  1. ??????? /// <summary>
  2. ??????? /// Task.Factory
  3. ??????? /// ContinueWhenAny和ContinueWhenAll
  4. ??????? /// ContinueWhenAll所指定的函式會(huì)在傳入的所有Tasks結(jié)束時(shí)執(zhí)行,只會(huì)執(zhí)行一次。
  5. ??????? /// ContinueWhenAny所指定的函式會(huì)在傳入的Tasks中有任何一個(gè)結(jié)束時(shí)執(zhí)行,且與ContinueWhenAll相同,只會(huì)執(zhí)行一次。
  6. ??????? /// </summary>
  7. ??????? private void Demo7()
  8. ??????? {
  9. ??????????? Task < int > t1 = Task .Factory.StartNew< int >(() =>
  10. ??????????? {
  11. ??????????????? int total = 0;
  12. ??????????????? for ( int i = 0; i < 10; i++)
  13. ??????????????????? total += i;
  14. ??????????????? Thread .Sleep(12000);
  15. ??????????????? return total;
  16. ??????????? });
  17. ??????????? Task < int > t2 = Task .Factory.StartNew< int >(() =>
  18. ??????????? {
  19. ??????????????? int total = 0;
  20. ??????????????? for ( int i = 10; i < 20; i++)
  21. ??????????????????? total += i;
  22. ??????????????? Thread .Sleep(10000);
  23. ??????????????? return total;
  24. ??????????? });
  25. ??????????? Task tfinal = Task .Factory.ContinueWhenAny< int >(
  26. ???????????????????????? new Task < int >[] { t1, t2 }, ( Task < int > task) =>
  27. ???????????????????????? {
  28. ???????????????????????????? if (task.Status == TaskStatus .RanToCompletion)
  29. ???????????????????????????? {
  30. ???????????????????????????????? Console .WriteLine(task.Result);
  31. ???????????????????????????? }
  32. ???????????????????????? });
  33. ??????????? Console .ReadLine();
  34. ??????? }

結(jié)論5:ContinueWhenAny和ContinueWhenAll對(duì)特定條件執(zhí)行,還是有些用處的。

?

?

好了,這篇文章算是完結(jié)了,4.0中的并行和線程確實(shí)簡(jiǎn)單了很多,使用起來(lái)也很方便,為了性能的提升還是要適當(dāng)?shù)氖褂孟隆?

謝謝觀賞

4.0中的并行計(jì)算和多線程詳解(二)


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號(hào)聯(lián)系: 360901061

您的支持是博主寫(xiě)作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對(duì)您有幫助就好】

您的支持是博主寫(xiě)作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長(zhǎng)會(huì)非常 感謝您的哦!!!

發(fā)表我的評(píng)論
最新評(píng)論 總共0條評(píng)論
主站蜘蛛池模板: 日喀则市| 改则县| 河源市| 镇赉县| 柳河县| 抚顺县| 登封市| 佳木斯市| 桦川县| 加查县| 金坛市| 云安县| 涟水县| 申扎县| 诸暨市| 玉门市| 望奎县| 余干县| 筠连县| 克拉玛依市| 蓬安县| 泽库县| 洞头县| 长乐市| 佛坪县| 高雄市| 曲周县| 同江市| 辽阳市| 根河市| 赞皇县| 河北省| 靖宇县| 和政县| 阜平县| 华池县| 福州市| 清镇市| 武夷山市| 会宁县| 巴塘县|