[英]Cannot cancel a task via CancellationTokenSource.Cancel()
我無法阻止任務。 首先,我剛開始使用任務。 以前,我一直在使用delegate.BeginInvoke()在后台運行,但這次我需要停止后台執行,如果需要的話。 所以我切換到了任務。 這是我的代碼:
CancellationTokenSource token = new CancellationTokenSource();
Task posting = Task.Factory.StartNew(() => DoPosting(docs, session), token.Token);
HttpRuntime.Cache[session.ToString() + "_token"] = token;
HttpRuntime.Cache[session.ToString() + "_task"] = posting;
這是ASP.NET MVC,所以我在HttpRuntime.Cache中存儲了持久的東西。 用戶可以通過此操作取消操作:
public JsonResult StopPosting(string session)
{
CancellationTokenSource token = (CancellationTokenSource)HttpRuntime.Cache.Get(session.ToString() + "_token");
Task posting = (Task)HttpRuntime.Cache[session.ToString() + "_task"];
token.Cancel();
return Json(new { Message = "Stopped!" });
}
現在,當這個動作第一次被擊中時,沒有任何反應。 然后我第二次要求取消。 現在,token.IsCancellationRequested說“true”,所以token.Cancel()必須做一些事情。 但是發布.Status仍然是“正在運行”。 它會保持這種狀態直到它完成,然后它是“RunToCompletion”。
所以,我要求取消任務,但它沒有被取消。
也許我做錯了什么或者我錯過了一些明顯的東西,但我無法看到/理解為什么它不會取消。
也許有人可以解釋一下?
問候。
取消令牌不會立即導致任務的委托在正確的位置停止執行。 支持(通過線程Abort
通過線程完成)可能會導致各種不良,包括未正確清理的對象,由於執行停止,因為執行在邏輯上被認為是原子的操作,等等而違反不變量,等等。
你需要做的是讓正在執行的函數看看CancellationToken並定期驗證它是否還沒有被取消。 除了將令牌傳遞給StartNew
您還需要將其傳遞給DoPosting
方法。 然后該方法需要定期調用token.ThrowIfCancellationRequested();
如果確實要求取消,那么在該方法中適當停止的地方。
請參閱如何取消不可取消的異步操作? 進一步閱讀。
我想你可能期待過多的CancellationToken。 關於任務,我認為CancellationToken僅在確定當任務的插槽可用時是否啟動任務時使用。 任務啟動后,任務框架不能簡單地在取消CancellationToken時中止委托調用。 為了完全取消這樣的事情,必須編寫Task框架(DoPosting)調用的代碼以了解CancellationToken,並且必須直接在代碼中的適當位置檢查該令牌的狀態。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.