C#連續(xù)任務Task.ContinueWith方法
一、簡介
通過任務,可以指定在任務完成之后,應開始運行之后另一個特定任務。ContinueWith是Task根據(jù)其自身狀況,決定后續(xù)應該作何操作。也就是說,在運行完task后,會執(zhí)行task.continuewith(XX)中的XX語句,但是是否執(zhí)行、如何執(zhí)行等需要看task的運行情況。例如:一個使用前一個任務的結果的新任務,如果前一個任務失敗了,這個任務就應執(zhí)行一些清理工作。任務處理程序都不帶參數(shù)或者帶一個對象參數(shù),而任務的連續(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();
}結果:

Start()和ContinueWith()的先后順序沒有關系,ContinueWith()會等待直到firstTask運行狀態(tài)達到 IsCompleted,因為TaskContinuationOptions中的OnlyOnRanToCompletion.必須指出的是,ContinueWith()中的參數(shù)是需要以Task為參數(shù)的,也就是firstTask作為參數(shù)被傳入,而且ContinueWith()運行在線程池中的線程中。我覺得比較重要的一點是:把ContinueWith()中的語句當做一塊新的語句塊,他們獨立于主線程。無論如何,他們都要被判斷,如果狀態(tài)(status)不滿足,那么他們不執(zhí)行;當指定了多個狀態(tài),則使用合理的對應狀態(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();
}
}結果:

這里主線程休眠了足足4秒鐘,足以讓firstTask和secondTask兩個任務完成運行,而后,由于secondTask的后續(xù)除了接受OnlyOnRanToCompletion外,還接受ExecuteSynchronously。因此,后續(xù)運行中,由于主線程還沒有結束,因此 ExecuteSynchronously得到認可,故secondTask的后續(xù)是在主線程上運行。
案例三:
代碼:
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();
}
}結果:

然而,如果把4秒鐘的休眠注釋掉,那么由于主線程很早就結束了,因此secondTask只能接受到OnlyOnRanToCompletion,因此還是運行在線程池中。
到此這篇關于C#連續(xù)任務Task.ContinueWith方法的文章就介紹到這了。希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關文章
C# WinForm中Panel實現(xiàn)用鼠標操作滾動條的實例方法
由于在WinForm中Panel不能直接響應鼠標的滾動事件,只好采用捕獲窗體的滾動事件。2013-03-03
C#操作本地文件及保存文件到數(shù)據(jù)庫的基本方法總結
C#使用System.IO中的文件操作方法在Windows系統(tǒng)中處理本地文件相當順手,這里我們還總結了在Oracle中保存文件的方法,嗯,接下來就來看看整理的C#操作本地文件及保存文件到數(shù)據(jù)庫的基本方法總結2016-05-05

