C# Task任務取消


需求:

在使用Blazor開發工具時,有個需求:
掃碼登錄頁面需要不斷輪詢接口獲取掃碼狀態,並在對應的狀態下進行對應的操作:刷新、登錄、跳轉等;
此時,為了不阻塞前端的響應,需要我們開啟一個線程進行狀態檢測,並在完成后結束線程任務;

方案:

使用取消令牌(CancellationTokenSource);
相對操作比較簡單,需要結束時調用Cancel(),同時,在Task內部進行IsCancellationRequested狀態監聽、或者使用暴力調用ThrowIfCancellationRequested()(同樣需要不間斷的調用,Cancel后才可觸發,本質上也是校驗IsCancellationRequested狀態);

var cts = new CancellationTokenSource();
var tk = cts.Token;

// 將CancellationToken傳入action中,然后對其取消狀態進行跟蹤
_ = Task.Factory.StartNew(async tk =>
{
    CancellationToken ct = (CancellationToken)tk;
    while (true)
    {
        ct.ThrowIfCancellationRequested();
        Console.WriteLine("循環中" + Thread.CurrentThread.ManagedThreadId);
        await Task.Delay(1000);
    }
}, tk, TaskCreationOptions.LongRunning);

// OR

// 此處是對於取消注冊個回調方法,在取消后進行調用
_ = Task.Factory.StartNew(async tk =>
{
    var state = true;
    CancellationToken ct = (CancellationToken)tk;
    ct.Register(() => 
    {
        state = false;
    });
    while (state)
    {
        Console.WriteLine("循環中" + Thread.CurrentThread.ManagedThreadId);
        await Task.Delay(1000);
    }

}, tk, TaskCreationOptions.LongRunning);

注意:

  • 在使用Task.Run() 或 Task.Factory.StartNew()時,有個參數為傳入CancellationToken,如:Run(Action, CancellationToken);該cancellationToken不會傳遞到Task內,更不會對Task內不造成影響,該cancellationToken 只是用於取消Run() 或 StartNew();
  • ck.Register可進行多次,構成鏈表執行,鏈表為倒敘的(最先注冊的最后執行);

擴展

CancellationTokenSource 具體實現源碼解析:淺談C#取消令牌CancellationTokenSource
相關項目:WeComLoad Demo


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM