第五节:Task构造函数之TaskCreationOptions枚举处理父子线程之间的关系。
一. 整體說(shuō)明
揭秘:
通過(guò)F12查看Task類(lèi)的源碼(詳見(jiàn)下面的截圖),發(fā)現(xiàn)Task類(lèi)的構(gòu)造函數(shù)有有一個(gè)參數(shù)為:TaskCreationOptions類(lèi)型,本章節(jié)可以算作是一個(gè)擴(kuò)展章節(jié),主要就來(lái)研究TaskCreationOptions類(lèi)的作用。
該類(lèi)主要用來(lái)處理父子線程之間的關(guān)系,重要的幾個(gè)參數(shù)如下:
①.AttachedToParent:指定將任務(wù)附加到任務(wù)層次結(jié)構(gòu)中的某個(gè)父級(jí),父任務(wù)必須等待所有子任務(wù)執(zhí)行完畢才能執(zhí)行
(下面的例子task線程必須等task1和task2線程執(zhí)行完畢才能執(zhí)行)
②. DenyChildAttach: 不允許子任務(wù)附加到父任務(wù)上
(下面例子task不再等待task1和task2,和00的默認(rèn)效果相同)
③. HideScheduler: 子任務(wù)不使用父類(lèi)Task的Scheduler,而是使用默認(rèn)的 (不進(jìn)行測(cè)試)
④. LongRunning:當(dāng)已知是長(zhǎng)時(shí)間運(yùn)行的任務(wù),可以使用該選項(xiàng) (不進(jìn)行測(cè)試)
⑤. PreferFairness:類(lèi)似于隊(duì)列的感覺(jué),盡可能公平的方式安排任務(wù) (不進(jìn)行測(cè)試)
?源碼如下:
1 // 摘要: 2 // 指定可控制任務(wù)的創(chuàng)建和執(zhí)行的可選行為的標(biāo)志。3 [Serializable]4 [Flags]5 public enum TaskCreationOptions6 {7 // 摘要: 8 // 指定應(yīng)使用默認(rèn)行為。9 None = 0, 10 // 11 // 摘要: 12 // 提示 System.Threading.Tasks.TaskScheduler 以一種盡可能公平的方式安排任務(wù),這意味著較早安排的任務(wù)將更可能較早運(yùn)行,而較晚安排運(yùn)行的任務(wù)將更可能較晚運(yùn)行。 13 PreferFairness = 1, 14 // 15 // 摘要: 16 // 指定某個(gè)任務(wù)將是運(yùn)行時(shí)間長(zhǎng)、粗粒度的操作。 它會(huì)向 System.Threading.Tasks.TaskScheduler 提示,過(guò)度訂閱可能是合理的。 17 LongRunning = 2, 18 // 19 // 摘要: 20 // 指定將任務(wù)附加到任務(wù)層次結(jié)構(gòu)中的某個(gè)父級(jí)。 21 AttachedToParent = 4, 22 // 23 // 摘要: 24 // 如果嘗試附有子任務(wù)到創(chuàng)建的任務(wù),指定 System.InvalidOperationException 將被引發(fā)。 25 DenyChildAttach = 8, 26 // 27 // 摘要: 28 // 防止環(huán)境計(jì)劃程序被視為已創(chuàng)建任務(wù)的當(dāng)前計(jì)劃程序。 這意味著像 StartNew 或 ContinueWith 創(chuàng)建任務(wù)的執(zhí)行操作將被視為 System.Threading.Tasks.TaskScheduler.Default 29 // 當(dāng)前計(jì)劃程序。 30 HideScheduler = 16, 31 }?
二. 實(shí)際測(cè)試
? 這里我們主要通過(guò)代碼來(lái)比較默認(rèn)情況下、AttachedToParent、DenyChildAttach之間的效果, task線程內(nèi)部有task1和task2線程,并且在task內(nèi)部開(kāi)啟。
1. 默認(rèn)情況
1 {2 Stopwatch watch = new Stopwatch();3 watch.Start();4 Console.WriteLine("----------------- Task多線程測(cè)試 --------------------------");5 Console.WriteLine("----------------- button1_Click 開(kāi)始 主線程id為:{0} --------------------------", Thread.CurrentThread.ManagedThreadId);6 7 #region 00-默認(rèn)8 {9 Task task = new Task(() => 10 { 11 Task task1 = new Task(() => 12 { 13 Thread.Sleep(1000); 14 Console.WriteLine("我是task1線程"); 15 }); 16 Task task2 = new Task(() => 17 { 18 Thread.Sleep(1000); 19 Console.WriteLine("我是task2線程"); 20 }); 21 22 task1.Start(); 23 task2.Start(); 24 }); 25 26 task.Start(); 27 task.Wait(); //單個(gè)線程的等待 28 Console.WriteLine("------------------我是主線程--------------------"); 29 } 30 #endregion 31 32 watch.Stop(); 33 Console.WriteLine("----------------- button1_Click 結(jié)束 主線程id為:{0} 總耗時(shí):{1}--------------------------", Thread.CurrentThread.ManagedThreadId, watch.ElapsedMilliseconds); 34 }多次執(zhí)行上述代碼看效果:發(fā)現(xiàn)task線程執(zhí)行完后,task1和task2才無(wú)序的執(zhí)行。
2.?AttachedToParent
作用:指定將任務(wù)附加到任務(wù)層次結(jié)構(gòu)中的某個(gè)父級(jí),父任務(wù)必須等待所有子任務(wù)執(zhí)行完畢才能執(zhí)行
1 {2 Task task = new Task(() =>3 {4 Task task1 = new Task(() =>5 {6 Thread.Sleep(3000);7 Console.WriteLine("我是task1線程");8 }, TaskCreationOptions.AttachedToParent);9 Task task2 = new Task(() => 10 { 11 Thread.Sleep(3000); 12 Console.WriteLine("我是task2線程"); 13 }, TaskCreationOptions.AttachedToParent); 14 15 task1.Start(); 16 task2.Start(); 17 }); 18 19 task.Start(); 20 task.Wait(); //單個(gè)線程的等待 21 Console.WriteLine("------------------我是主線程--------------------"); 22 }? 多次執(zhí)行上述代碼看效果:發(fā)現(xiàn)task線程必須等task1和task2執(zhí)行完畢后才能執(zhí)行(印證了AttachedToParent的作用),task1和task2無(wú)先后順序。
3.?DenyChildAttach
? 作用:不允許子任務(wù)附加到父任務(wù)上。
1 {2 Task task = new Task(() =>3 {4 Task task1 = new Task(() =>5 {6 Thread.Sleep(3000);7 Console.WriteLine("我是task1線程");8 }, TaskCreationOptions.AttachedToParent);9 Task task2 = new Task(() => 10 { 11 Thread.Sleep(3000); 12 Console.WriteLine("我是task2線程"); 13 }, TaskCreationOptions.AttachedToParent); 14 15 task1.Start(); 16 task2.Start(); 17 }, TaskCreationOptions.DenyChildAttach); 18 19 task.Start(); 20 task.Wait(); //單個(gè)線程的等待 21 Console.WriteLine("------------------我是主線程--------------------"); 22 }?多次執(zhí)行上述代碼看效果:發(fā)現(xiàn)task線程執(zhí)行完后,task1和task2才無(wú)序的執(zhí)行。(和上述的默認(rèn)情況是一致的)
總結(jié)
以上是生活随笔為你收集整理的第五节:Task构造函数之TaskCreationOptions枚举处理父子线程之间的关系。的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 迄今最大最详细的银河系地图发布!涵盖20
- 下一篇: 【转】SPSite、SPWeb对象模型(