工作取消
System.Threading.Tasks.Task 和 System.Threading.Tasks.Task<TResult> 類別可使用取消語彙基元來支援取消作業,這是 .NET Framework 4 的新功能。 如需詳細資訊,請參閱 取消。 在工作類別中,取消程序包括使用者委派之間的合作,這代表可取消的作業和要求取消的程式碼。成功的取消包括要求程式碼呼叫 CancellationTokenSource.Cancel 方法,以及由使用者委派適時終止作業。 您可以使用下列選項之一來終止作業:
藉由直接從委派傳回。 在許多情況下使用此選項即已足夠;但以此方式「取消」的工作執行個體將會轉換至 RanToCompletion 狀態,而非 Canceled 狀態。
擲回 OperationCanceledException,並將其傳遞至據以要求取消的語彙基元。 執行此作業的常見方式是使用 ThrowIfCancellationRequested 方法。 以此方式取消的工作會切換至 Canceled 狀態,可供呼叫端節點用以驗證工作已回應其取消要求。
下列範例說明會擲回例外狀況的工作取消基本模式。 請注意,語彙基元不但會傳遞至使用者委派,也會傳遞至工作執行個體本身。
Imports System.Threading
Imports System.Threading.Tasks
Module Test
Sub Main()
Dim tokenSource2 As New CancellationTokenSource()
Dim ct As CancellationToken = tokenSource2.Token
Dim t2 = Task.Factory.StartNew(Sub()
' Were we already canceled?
ct.ThrowIfCancellationRequested()
Dim moreToDo As Boolean = True
While moreToDo = True
' Poll on this property if you have to do
' other cleanup before throwing.
If ct.IsCancellationRequested Then
' Clean up here, then...
ct.ThrowIfCancellationRequested()
End If
End While
End Sub _
, tokenSource2.Token) ' Pass same token to StartNew.
' Cancel the task.
tokenSource2.Cancel()
' Just continue on this thread, or Wait/WaitAll with try-catch:
Try
t2.Wait()
Catch e As AggregateException
For Each item In e.InnerExceptions
Console.WriteLine(e.Message & " " & item.Message)
Next
End Try
Console.ReadKey()
End Sub
End Module
using System;
using System.Threading;
using System.Threading.Tasks;
class Program
{
static void Main()
{
var tokenSource2 = new CancellationTokenSource();
CancellationToken ct = tokenSource2.Token;
var task = Task.Factory.StartNew(() =>
{
// Were we already canceled?
ct.ThrowIfCancellationRequested();
bool moreToDo = true;
while (moreToDo)
{
// Poll on this property if you have to do
// other cleanup before throwing.
if (ct.IsCancellationRequested)
{
// Clean up here, then...
ct.ThrowIfCancellationRequested();
}
}
}, tokenSource2.Token); // Pass same token to StartNew.
tokenSource2.Cancel();
// Just continue on this thread, or Wait/WaitAll with try-catch:
try
{
task.Wait();
}
catch (AggregateException e)
{
foreach (var v in e.InnerExceptions)
Console.WriteLine(e.Message + " " + v.Message);
}
Console.ReadKey();
}
}
如需更完整的範例,請參閱 HOW TO:取消工作及其子系。
工作執行個體在觀察到由使用者程式碼擲回的 OperationCanceledException 時,會比較此例外狀況的語彙基元及與它自己相關聯的語彙基元 (即傳遞給建立工作之 API 的語彙基元)。 如果兩者相同,且此語彙基元的 IsCancellationRequested 屬性傳回 true,則工作會將此解譯成確認取消,並轉換至 Canceled 狀態。 如果未使用 Wait 或 WaitAll 方法等候工作,則工作只會將其狀態設為 Canceled。
如果您正在等候轉換至 Canceled 狀態的工作,則會產生並擲回 TaskCanceledException (包在 AggregateException 中)。 請注意,此例外狀況表示取消成功,而非錯誤情況。 因此,工作的例外狀況屬性會傳回 null。
如果語彙基元的 IsCancellationRequested 屬性傳回 false,或例外狀況的語彙基元不符合工作的語彙基元,則 OperationCanceledException 會被視為一般例外狀況,而使工作轉換至 Faulted 狀態。 同時也請注意,如有其他例外狀況存在,也會使工作轉換至 Faulted 狀態。 您可以在 Status 屬性中取得已完成工作的狀態。
不過,在要求取消之後,工作仍有可能會繼續處理某些項目。