2011-04-12 48 views
2

專家一個說法,我曾經使用象Task.Factory.StartNew(new Action(()=>{}), cancellationToken);關於產品在使用任務

的方法我有關於第二個參數cancellationToken問題。因爲cancellationToken是我方法中的一個變量,所以在lambda表達式中,我可以像使用msdn一樣使用該字段來取消我的任務;我不確定這是推薦。在這種情況下,這裏需要第二個參數嗎?它在StartNew方法中傳遞,但沒有實際使用。我們需要使用這個參數嗎?

回答

2

如果要取消任務,則需要此參數。如果你的應用程序不支持或要求取消,那麼你可以只說

Task.Factory.StartNew(() => { ... }); 

注意,取消是合作使你的代碼必須輪詢取消和作出相應的反應。

例如:

CancellationTokenSource cts = new CancellationTokenSource(); 
CancellationToken token = cts.Token; 

Task myTask = Task.Factory.StartNew(() => 
    { 
     for (...) 
     { 
      token.ThrowIfCancellationRequested(); 

      // Body of for loop. 
     } 
    }, token); 

    // ... elsewhere ... 
    cts.Cancel(); 

你必須取消令牌傳遞到否則它不會附加到任務的方法。方法內的代碼僅使用令牌來響應取消,或者拋出或使用IsCancellationRequested關閉。儘管一個任務可以從lambda內部取消,我想。任務本身也需要令牌。

這裏的一些進一步澄清:

傳遞令牌到StartNew 與帶任務令牌。 這有兩個主要好處:1)如果 令牌在任務開始執行前已取消請求 ,則該任務將不會執行。將 轉換爲Running,而不是 立即轉換爲Cancelled。 這樣可以避免運行 任務時的成本,如果它在運行過程中僅取消 。 2)如果任務的身體 也監測 取消標記,並拋出包含 該令牌(這是什麼 ThrowIfCancellationRequested做一個 OperationCanceledException), 那麼當任務看到OCE,它 檢查是否OCE的令牌匹配 任務的標記。如果是,則 例外將被視爲 確認合作伙伴 取消並且任務轉換 爲取消狀態(而不是 錯誤狀態)。

http://social.msdn.microsoft.com/Forums/en/parallelextensions/thread/c2f614f6-c96c-4821-84cc-050b21aaee45

看到這裏取消一般性討論:爲進一步討論

http://msdn.microsoft.com/en-us/library/ff963549.aspx

+0

我只是認爲我們可以調用token.ThrowIfCancellationRequested()與我的變量,我們不使用它在lambda作爲參數。請不要誤解我的意思;如果我聲明瞭一個cancellationToken變量,並且不會將它傳遞給StartNew方法,我仍然可以使用這個變量來取消我的任務,對嗎? 感謝您的回覆。 – Howard 2011-04-12 03:29:03

+0

嗨Ade,我猜Howard的意思是這樣的:如果我想取消任務,我可以在我的lambda表達式中使用cancellationToken,因爲在整個方法中可以看到cancellationToken。現在爲什麼我必須將它傳遞給StartNew? StartNew方法是否以某種方式在內部使用該令牌? – CuiPengFei 2011-04-12 03:33:26

+0

已經更新的答案。 – 2011-04-12 03:40:50