C#連續(xù)任務(wù)Task.ContinueWith方法
一、簡介
通過任務(wù),可以指定在任務(wù)完成之后,應(yīng)開始運(yùn)行之后另一個特定任務(wù)。ContinueWith是Task根據(jù)其自身狀況,決定后續(xù)應(yīng)該作何操作。也就是說,在運(yùn)行完task后,會執(zhí)行task.continuewith(XX)中的XX語句,但是是否執(zhí)行、如何執(zhí)行等需要看task的運(yùn)行情況。例如:一個使用前一個任務(wù)的結(jié)果的新任務(wù),如果前一個任務(wù)失敗了,這個任務(wù)就應(yīng)執(zhí)行一些清理工作。任務(wù)處理程序都不帶參數(shù)或者帶一個對象參數(shù),而任務(wù)的連續(xù)處理方法都有一個Task類型的參數(shù)。
二、案例
案例一:
代碼:
static int TaskMethod(string name, int seconds) { Console.WriteLine("Frist Task Method : Task {0} is running on a thread id: {1}. Is thread pool thread: {2}", name, Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread); Thread.Sleep(TimeSpan.FromSeconds(seconds)); return 60 * seconds; } static void Main(string[] args) { var FirstTask = new Task<int>(() => TaskMethod("Frist Task", 3)); FirstTask.ContinueWith(t => Console.WriteLine("Frist Task Result: {0}. Thread id: {1}, Is in Thred Pool: {2}", t.Result, Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread), TaskContinuationOptions.OnlyOnRanToCompletion);//線程池線程 FirstTask.Start(); Console.ReadKey(); }
結(jié)果:
Start()和ContinueWith()的先后順序沒有關(guān)系,ContinueWith()會等待直到firstTask運(yùn)行狀態(tài)達(dá)到 IsCompleted,因?yàn)門askContinuationOptions中的OnlyOnRanToCompletion.必須指出的是,ContinueWith()中的參數(shù)是需要以Task為參數(shù)的,也就是firstTask作為參數(shù)被傳入,而且ContinueWith()運(yùn)行在線程池中的線程中。我覺得比較重要的一點(diǎn)是:把ContinueWith()中的語句當(dāng)做一塊新的語句塊,他們獨(dú)立于主線程。無論如何,他們都要被判斷,如果狀態(tài)(status)不滿足,那么他們不執(zhí)行;當(dāng)指定了多個狀態(tài),則使用合理的對應(yīng)狀態(tài)。
案例二:
代碼:
class Program { static int TaskMethod(string name, int seconds) { Console.WriteLine("Task Method : Task {0} is running on a thread id: {1}. Is thread pool thread: {2}", name, Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread); Thread.Sleep(TimeSpan.FromSeconds(seconds)); return 60 * seconds; } static void Main(string[] args) { Console.WriteLine("Main Thread id {0}, Is in Thred Pool: {1}", Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread); var firstTask = new Task<int>(() => TaskMethod("frist task", 3)); var secondTask = new Task<int>(() => TaskMethod("second task", 2)); firstTask.ContinueWith(t => Console.WriteLine("Result:Frist Thread Result: {0}. Thread id: {1}, Is in Thred Pool: {2}", t.Result, Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread), TaskContinuationOptions.OnlyOnRanToCompletion); firstTask.Start(); secondTask.Start(); Thread.Sleep(TimeSpan.FromSeconds(4)); //給予足夠時間,讓firstTask、secondTask及其后續(xù)操作執(zhí)行完畢。 Task continuation = secondTask.ContinueWith(t => Console.WriteLine("Result:Second Thread Result: {0}. Thread id: {1}, Is in Thred Pool: {2}", t.Result, Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread), TaskContinuationOptions.OnlyOnRanToCompletion | TaskContinuationOptions.ExecuteSynchronously); Console.ReadLine(); Console.ReadKey(); } }
結(jié)果:
這里主線程休眠了足足4秒鐘,足以讓firstTask和secondTask兩個任務(wù)完成運(yùn)行,而后,由于secondTask的后續(xù)除了接受OnlyOnRanToCompletion外,還接受ExecuteSynchronously。因此,后續(xù)運(yùn)行中,由于主線程還沒有結(jié)束,因此 ExecuteSynchronously得到認(rèn)可,故secondTask的后續(xù)是在主線程上運(yùn)行。
案例三:
代碼:
class Program { static int TaskMethod(string name, int seconds) { Console.WriteLine("Task Method : Task {0} is running on a thread id: {1}. Is thread pool thread: {2}", name, Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread); Thread.Sleep(TimeSpan.FromSeconds(seconds)); return 60 * seconds; } static void Main(string[] args) { Console.WriteLine("Main Thread id {0}, Is in Thred Pool: {1}", Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread); var firstTask = new Task<int>(() => TaskMethod("frist task", 3)); var secondTask = new Task<int>(() => TaskMethod("second task", 2)); firstTask.ContinueWith(t => Console.WriteLine("Result:Frist Thread Result: {0}. Thread id: {1}, Is in Thred Pool: {2}", t.Result, Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread), TaskContinuationOptions.OnlyOnRanToCompletion); firstTask.Start(); secondTask.Start(); //Thread.Sleep(TimeSpan.FromSeconds(4)); //給予足夠時間,讓firstTask、secondTask及其后續(xù)操作執(zhí)行完畢。 Task continuation = secondTask.ContinueWith(t => Console.WriteLine("Result:Second Thread Result: {0}. Thread id: {1}, Is in Thred Pool: {2}", t.Result, Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread), TaskContinuationOptions.OnlyOnRanToCompletion | TaskContinuationOptions.ExecuteSynchronously); Console.ReadLine(); Console.ReadKey(); } }
結(jié)果:
然而,如果把4秒鐘的休眠注釋掉,那么由于主線程很早就結(jié)束了,因此secondTask只能接受到OnlyOnRanToCompletion,因此還是運(yùn)行在線程池中。
到此這篇關(guān)于C#連續(xù)任務(wù)Task.ContinueWith方法的文章就介紹到這了。希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
C#、.Net中把字符串(String)格式轉(zhuǎn)換為DateTime類型的三種方法
這篇文章主要介紹了C#、.Net中把字符串(String)格式轉(zhuǎn)換為DateTime類型的三種方法,本文總結(jié)了Convert.ToDateTime(string)、Convert.ToDateTime(string, IFormatProvider)、DateTime.ParseExact()三種方法,需要的朋友可以參考下2015-07-07C#設(shè)計(jì)模式編程中運(yùn)用適配器模式結(jié)構(gòu)實(shí)戰(zhàn)演練
這篇文章主要介紹了C#設(shè)計(jì)模式編程中運(yùn)用適配器模式結(jié)構(gòu)實(shí)戰(zhàn)演練,并總結(jié)了適配器模式的優(yōu)缺點(diǎn)和適用場景以及.NET框架中的應(yīng)用,需要的朋友可以參考下2016-02-02C#調(diào)用C++的dll兩種實(shí)現(xiàn)方式(托管與非托管)
這篇文章主要介紹了C#調(diào)用C++的dll兩種實(shí)現(xiàn)方式(托管與非托管),具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2023-08-08c#高效率導(dǎo)出多維表頭excel的實(shí)例代碼
這篇文章介紹了c#高效率導(dǎo)出多維表頭excel的實(shí)例代碼,有需要的朋友可以參考一下2013-11-11C#使用Post調(diào)用接口并傳遞json參數(shù)
這篇文章主要介紹了C#使用Post調(diào)用接口并傳遞json參數(shù),具有很好的參考價值,希望對大家有所幫助。2022-06-06C#實(shí)現(xiàn)在啟動目錄創(chuàng)建快捷方式的方法
這篇文章主要介紹了C#實(shí)現(xiàn)在啟動目錄創(chuàng)建快捷方式的方法,涉及C#快捷方式的創(chuàng)建技巧,具有一定參考借鑒價值,需要的朋友可以參考下2015-09-09詳解DataGridView控件的數(shù)據(jù)綁定
本文詳細(xì)講解了DataGridView控件的數(shù)據(jù)綁定,文中通過示例代碼介紹的非常詳細(xì)。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-02-02