1. 建立可取消操作的Task
一個任務Task開始之後,我們可以根據需要對任務進行取消,以便停止目前執行的操作.代碼如下:
static void Main(string[] args)
{
CancellationTokenSource s = new CancellationTokenSource();
CancellationToken token = s.Token;
Task task = new Task(() =>
{
for (int i = 0; i < int.MaxValue; i++)
{
if (token.IsCancellationRequested)
{
Console.WriteLine("任務被取消");
throw new OperationCanceledException(token);
}
else
Console.WriteLine("目前值 {0}", i);
}
}
}, token);
token.Register(() =>
{
Console.WriteLine("任務取消時執行的委托方法");
});
task.Start();
Console.ReadLine();
Console.WriteLine("取消任務.");
s.Cancel();
Console.WriteLine("Main執行完畢.");
Console.ReadLine();
}
從上面的代碼示例中,我們可以看到建立可取消任務Task的過程是:先建立一個可取消操作的源CancellationTokenSource的一個對象,然後使用CancellationTokenSource的可取消操作結構對象CancellationToken,并使用該結構初始化一個任務Task,最後通過調用可取消操作的源的Cancel()方法,來取消目前關聯任務的操作.
簡單的了解,就是将一個任務Task與可取消操作的源CancellationTokenSource通過CancellationToken關聯起來通過CancellationTokenSource的取消方法來通知相應的任務取消操作.(可以使用某個CancellationToken初始化多個任務Task,然後在調用CancellationTokenSource的取消方法時,則該多個任務也将被通知取消,進而到達一次取消多個任務的目的)。
在上面的代碼,可以看到:
Ø token.IsCancellationRequested,它是擷取是否已請求取消此标記, 如果此屬性為 true,則隻能保證已請求取消。 它不保證每個注冊的處理程式已完成執行,也不能保證取消請求已完成傳播到所有注冊的處理程式.也就是說,此屬性隻是可以得到一個任務ask擷取到了取消标記,但它不能代表此任務已經停止完畢或執行完畢取消時注冊的事件(token.Register)。
Ø token.Register(…)向該任務注冊一個取消的委托,在任務被取消時,将會執行此委托。
通過上面的代碼,我們應該學會了如何建立一個可以被取消的任務Task,如何判斷一個任務Task已經被通知被取消,如何給一個任務Task注冊一個取消的處理程式。此外,Task類的IsCanceled屬性可以執行任務是否被取消執行完畢。
2. Task的等待
任務Task可以在某些時候去等待某個事件發生或者等待其他任務執行完畢,Task提供了:
Ø Wait(等待某個事件發生,這就好比:請客吃飯,等一個朋友到來我們就吃飯。)。
Ø WaitAll(等待某組事件中全部事件都已發生,這就好比:請客吃飯,必須等所有受邀的朋友都到齊才能吃飯)。
Ø WaitAny(等待某組事件中任何一個事件都已發生,這就好比:請客吃飯,隻要所有受邀的朋友中有任何一個朋友,不論是誰,隻要有朋友到了,我們就開始吃飯)。
相應的,這些方法也有很多重載。
下面來看看具體的代碼:
static void WaitTask()
CancellationTokenSource ts = newCancellationTokenSource();
CancellationToken token = ts.Token;
Task task1 = new Task(() =>
for (int i = 0; i < 10; i++)
token.ThrowIfCancellationRequested();
Console.WriteLine("任務1中i的值是{0}", i);
token.WaitHandle.WaitOne(1 * 1000);
}
Console.WriteLine("任務1執行完畢");
}, token);
Console.WriteLine("任務1 目前狀态:{0}", task1.Status.ToString());
Task task2 = new Task(() =>
Console.WriteLine("任務2執行完畢");
task1.Start();
task2.Start();
Console.WriteLine("任務1 目前狀态:{0}", task1.Status.ToString());
Console.WriteLine("等待所有任務執行完畢…..");
Task.WaitAll(task1, task2);
Console.WriteLine("任務1 目前狀态:{0}", task1.Status.ToString());
Console.WriteLine("所有任務全部執行完畢.");
Console.ReadLine();
需要說明的是:
Ø 代碼token.ThrowIfCancellationRequested();與if(token.IsCancellationRequested) throw new OperationCanceledException(token);是完全等效,隻是不同的寫法而已。
Ø 代碼token.WaitHandle.WaitOne(1*1000)是目前執行該代碼的任務Task休息1秒中,類似Threed.Sleep(1*1000)。
Ø Task.WaitAll(task1,task2….)是等待所有的任務。
Ø Task 的Status 擷取此任務的 TaskStatus。
其中TaskStatus枚舉有:
(1) Created 該任務已初始化,但尚未被計劃。
(2) WaitingForActivation 該任務正在等待 .NET Framework 基礎結構在内部将其激活并進行計劃。
(3) WaitingToRun 該任務已被計劃執行,但尚未開始執行。
(4) Running 該任務正在運作,但尚未完成。
(5) WaitingForChildrenToComplete 該任務已完成執行,正在隐式等待附加的子任務完成。
(6) RanToCompletion 已成功完成執行的任務。
(7) Canceled 該任務已認證對其自身的 CancellationToken 引發 OperationCanceledException 對取消進行了确認,此時該标記處于已發送信号狀态;或者在該任務開始執行之前,已向該任務的 CancellationToken 發出了信号。
(8) Faulted 由于未處理異常的原因而完成的任務。
此外,Task還有以下幾個重要屬性
Ø IsCanceled 擷取此 Task 執行個體是否由于被取消的原因而已完成執行。
Ø IsCompleted 擷取此 Task 是否已完成。
Ø IsFaulted 擷取 Task 是否由于未經處理異常的原因而完成。
好,本節介紹完畢。
本文轉自風車車 部落格園部落格,原文連結:http://www.cnblogs.com/xray2005/archive/2011/08/22/2148815.html,如需轉載請自行聯系原作者