程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> Task類(任務),task類任務

Task類(任務),task類任務

編輯:C#入門知識

Task類(任務),task類任務


任務表示應完成的某個單元的工作。這個單元的工作可以在單獨的線程中運行,也可以以同步方式啟動一個任務,這需要等待主調用線程。使用任務不僅可以獲得一個抽象層,還可以對底層線程進行很多控制。

1.啟動任務

要啟動任務,可以使用TaskFactory類或Task類的構造函數和Start()方法。Task類的構造函數在創建任務上提供的靈活性較大。

1).任務方法

static object taskMethodLock = new object(); static void TaskMethod(object title) { lock (taskMethodLock) { Console.WriteLine(title); Console.WriteLine("Task id: {0}, thread: {1}", Task.CurrentId == null ? "no task" : Task.CurrentId.ToString(), Thread.CurrentThread.ManagedThreadId); Console.WriteLine("is pooled thread: {0}", Thread.CurrentThread.IsThreadPoolThread); Console.WriteLine("is background thread: {0}", Thread.CurrentThread.IsBackground); Console.WriteLine(); } } View Code

2).使用線程池的任務

static void TasksUsingThreadPool() { var tf = new TaskFactory(); Task t1 = tf.StartNew(TaskMethod, "using a task factory"); Task t2 = Task.Factory.StartNew(TaskMethod, "factory via a task"); var t3 = new Task(TaskMethod, "using a task constructor and Start"); t3.Start(); Task t4 = Task.Run(() => TaskMethod("using the Run method")); } View Code

執行結果:

3).同步任務

任務也可以同步運行,已相同的線程作為主調用線程。

注:主線程是一個調用前台線程,沒有任務ID,也不是線程池中的線程。

private static void RunSynchronousTask() { TaskMethod("just the main thread"); var t1 = new Task(TaskMethod, "run sync"); t1.RunSynchronously(); } View Code

執行結果:

4).使用單獨線程的任務

如果任務的代碼應該長時間運行,就應該使用TaskCreationOptions.LogRunning告訴任務調度器創建一個新線程,而不是使用線程池中的線程。

private static void LongRunningTask() { var t1 = new Task(TaskMethod, "long running", TaskCreationOptions.LongRunning); t1.Start(); } View Code

執行結果:

2.Future——任務結果

任務結束時,它可以把一些有用的狀態信息寫到共享對象中。這個對象必須是線程安全的。另一個選項是使用返回某個結果的任務。這種任務也叫Future,因為它返回一個結果。

static Tuple<int, int> TaskWithResult(object division) { Tuple<int, int> div = (Tuple<int, int>)division; int result = div.Item1 / div.Item2; int reminder = div.Item1 % div.Item2; Console.WriteLine("task creates a result..."); return Tuple.Create<int, int>(result, reminder); } View Code static void ResultsFromTasks() { var t1 = new Task<Tuple<int, int>>(TaskWithResult, Tuple.Create<int, int>(8, 3)); t1.Start(); Console.WriteLine(t1.Result); t1.Wait(); Console.WriteLine("result from task: {0} {1}", t1.Result.Item1, t1.Result.Item2); } View Code

執行結果:

3.連續任務

通過任務,可以指定在任務完成後,應開始運行另一個特定任務。

注:無論前一個任務是如何結束的,前面的連續任務總是在前一個任務結束時啟動。使用TaskContinuationOptions枚舉中的值,可以指定,連續任務只有在起始任務成功(或失敗)結束時啟動。一些可能的值是OnlyOnFaulted、NotOnFaulted、OnlyOnCanceled和OnlyOnRanToCompletion。

static void DoOnFirst() { Console.WriteLine("doing some task {0}", Task.CurrentId); Thread.Sleep(3000); } static void DoOnSecond(Task t) { Console.WriteLine("task {0} finished", t.Id); Console.WriteLine("this task id {0}", Task.CurrentId); Console.WriteLine("do some cleanup"); Thread.Sleep(3000); } static void DoOnError(Task t) { Console.WriteLine("task {0} had an error!", t.Id); Console.WriteLine("my id {0}", Task.CurrentId); Console.WriteLine("do some cleanup"); } View Code static void ContinuationTask() { Task t1 = new Task(DoOnFirst); Task t2 = t1.ContinueWith(DoOnSecond); Task t3 = t1.ContinueWith(DoOnSecond); Task t4 = t2.ContinueWith(DoOnSecond); Task t5 = t1.ContinueWith(DoOnError, TaskContinuationOptions.OnlyOnFaulted); t1.Start(); Thread.Sleep(5000); } View Code

執行結果:

4.任務層次結構

利用任務連續性,可以在一個任務結束後啟動另一個任務。任務也可以構成一個層次結構。一個任務啟動一個新任務時,就啟動了一個父/子層次結構。

如果父任務在子任務之前結束,父任務的狀態就顯示為:WaitingForChildrenToComplete。所有的子任務也結束時,父任務的狀態就變成RanToCompletion。

static void ParentAndChild() { var parent = new Task(ParentTask); parent.Start(); Thread.Sleep(2000); Console.WriteLine(parent.Status); Thread.Sleep(4000); Console.WriteLine(parent.Status); } static void ParentTask() { Console.WriteLine("task id {0}", Task.CurrentId); var child = new Task(ChildTask); // , TaskCreationOptions.DetachedFromParent); child.Start(); Thread.Sleep(1000); Console.WriteLine("parent started child"); // Thread.Sleep(3000); } static void ChildTask() { // Console.WriteLine("task id {0}, parent: {1}", Task.Current.Id, Task.Current.Parent.Id); Console.WriteLine("child"); Thread.Sleep(5000); Console.WriteLine("child finished"); } View Code

執行結果:

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved