本文主要介紹使用CancellationTokenSource調(diào)度并行運(yùn)行的Task。
有多個(gè)Task并行運(yùn)行時(shí),如果其中一個(gè)Task所運(yùn)行的程序出現(xiàn)異常,我們想馬上終止所有待執(zhí)行的Task。這樣對(duì)系統(tǒng)的性能等各個(gè)方面都是有好處的。
public class Handler { public void DoSomething(CancellationTokenSource cts, int index) { if (cts.IsCancellationRequested) { return; } if (index == 2) { cts.Cancel(); } Console.WriteLine(index); } }
兩點(diǎn):
public class AppClient { public static void Main() { var cts = new CancellationTokenSource(); var childTasks = new List<Task>(); var parentTask = new Task(() => { var taskFactory = new TaskFactory(cts.Token, TaskCreationOptions.AttachedToParent, TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Default); for (var i = 0; i < 100; i++) { var tempIndex = i; var childTask = taskFactory.StartNew(() => new Handler().DoSomething(cts, tempIndex)); childTasks.Add(childTask); } foreach (var task in childTasks) { task.ContinueWith(t => cts.Cancel(), TaskContinuationOptions.OnlyOnFaulted); } }); parentTask.Start(); parentTask.Wait(); Console.Read(); } }
上面的代碼在正常情況下會(huì)有100個(gè)Task產(chǎn)生,會(huì)Attach到父Task上,由父Task統(tǒng)一調(diào)度(parentTask.Start; parentTask.Wait)
foreach (var task in childTasks){ task.ContinueWith(t => cts.Cancel(), TaskContinuationOptions.OnlyOnFaulted);}
這塊代碼的主要含義是當(dāng)task發(fā)生錯(cuò)誤,比如拋出異常的時(shí)候,對(duì)cts發(fā)起取消。這樣cts處于取消狀態(tài)后(IsCancellationRequested==true),后續(xù)的操作都會(huì)直接return,不再執(zhí)行。
這就回到了本文開始的話題:有多個(gè)Task并行運(yùn)行時(shí),如果其中一個(gè)Task所運(yùn)行的程序出現(xiàn)異常,我們想馬上終止所有待執(zhí)行的Task。這樣對(duì)系統(tǒng)的性能等各個(gè)方面都是有好處的。
并行編程打算寫一個(gè)系列的文章好好總結(jié)一下。
新聞熱點(diǎn)
疑難解答
圖片精選
網(wǎng)友關(guān)注