2012-08-09 93 views
6

我已經定義了以下任務ContinueWith已取消的任務

var t = Task.Factory.StartNew(
    () => LongRunningMethod(cancellationToken), 
    cancellationToken 
); 

t.ContinueWith(
    Callback, 
    cancellationToken, 
    TaskContinuationOptions.None, 
    TaskScheduler.FromCurrentSynchronizationContext() 
); 

LongRunningMethod裏面,我檢查取消標記已請求取消,如果是這樣,我從方法返回。這很好。

但是,在這種情況下不會調用回調。回調確實被調用,如果我取代以上

t.ContinueWith(
    x => Callback(x, cancellationToken), 
    TaskScheduler.FromCurrentSynchronizationContext() 
); 

在這種情況下,任務仍然認爲它運行完成第二行。

爲什麼第一個電話不工作?我的印象是TaskContinuationOptions.None意味着無論線程的狀態如何,回調都會被調用。

我取消任務致電:

_cancellationTokenSource.Cancel(); 

在一個有點相關的說明,不必繞過取消標記好像任務庫的主要設計缺陷。

回答

12

您的繼續任務需要取消CancellationToken。這意味着繼續任務在未啓動時被取消。不要將該標記傳遞給您不想取消的事物。

CancellationToken旨在一次取消整個動作圖。您可以通過不傳遞令牌來排除取消內容。

+0

然後TaskContinuationOptions.None做什麼?如果我說TaskContinuationOptions.OnlyOnCancelled,那也不起作用。 – user981225 2012-08-09 21:42:31

+1

如果* parent *任務被取消,TaskContinuationOptions提供了一種不執行的方法。 CancellationToken參數是獨立的。 – usr 2012-08-09 21:54:28