2016-05-14 49 views

回答

2

一些試驗後,我想出了soulution:

HostingEnvironment.QueueBackgroundWorkItem(ct => 
{ 
    var linkedTokenSource = CancellationTokenSource.CreateLinkedTokenSource(ct); 
    var cancellationToken = linkedTokenSource.Token; 
    return Task.Factory.StartNew(() => 
    { 
     // do stuff on background 
    }, cancellationToken); 
}); 

更新:事實上,不需要

任務。謝謝svick帶來了。 這是一個沒有任務的更詳細的代碼示例。

HostingEnvironment.QueueBackgroundWorkItem(ct => 
{ 
    var linkedTokenSource = CancellationTokenSource.CreateLinkedTokenSource(ct); 
    // following is a dummy method, but you get the idea. 
    // StoreCancellationTokenSourceSoItCanBeUsedSomewhereElse(linkedTokenSource); 

    var cancellationToken = linkedTokenSource.Token; 

    try 
    { 
     while(true) 
     { 
      cancellationToken.ThrowIfCancellationRequested(); 
      // do bg stuff 
     } 
    } 
    catch (OperationCanceledException ex) 
    { 
     // either token is in cancelled state 
    } 
}); 
+0

你不需要在單獨的'Task'上運行代碼就可以取消它。 – svick

+0

在幕後,如果使用其他過載,則無論如何都會創建任務。通過創建鏈接的令牌源,我必須只管理一個cancallation令牌。參考:https://msdn.microsoft.com/en-us/library/system.threading.cancellationtokensource.createlinkedtokensource(v=vs.110).aspx「創建一個CancellationTokenSource,將取消狀態時,任何源代幣處於取消狀態。「 – maxlego

+0

[我沒有看到任何'任務'創建那裏](http://referencesource.microsoft.com/#System.Web/Hosting/HostingEnvironment.cs,32c143ca4ed232c1)(和我一路看到的地方,代碼實際執行)。如果你想結合兩種取消方式,那麼'CreateLinkedTokenSource()'是正確的解決方案,我沒有說任何反對。 – svick

1

HostingEnvironment.QueueBackgroundWorkItem的簽名是:

public static void QueueBackgroundWorkItem(Action<CancellationToken> workItem) 

這意味着,一個工作項獲得訪問CancellationToken。但我認爲這對你的情況並不有用。從the documentation

提供的CancellationToken將在應用程序關閉時發出信號。

如果你想取消基於一些其他條件workItem,您可以使用單獨的CancellationToken,你從一個CancellationTokenSource創建。例如,要取消工作項目,如果它不10秒內啓動:

var cts = new CancellationTokenSource(TimeSpan.FromSeconds(10)); 

HostingEnvironment.QueueBackgroundWorkItem(_ => 
{ 
    cts.Token.ThrowIfCancellationRequested(); 

    // the code of the work item goes here 
}); 

這將在技術上還是開始工作的項目,即使CancellationToken被取消,但它不會做任何事情。

請注意,取消總是合作。這意味着如果您有一個長期運行的工作項目,並且您想在執行過程中取消它,則需要定期檢查CancellationToken