# 關於 CancellationToken 使用說明 ###### tags: `C#` ## 前言 在撰寫[Task 建構函式](https://docs.microsoft.com/zh-tw/dotnet/api/system.threading.tasks.task.-ctor?view=net-6.0)時可以發現有一個`CancellationToken`的參數,這個參數一值沒有去使用到,但因任務需求要在程序下同時執行多個host任務這才發現其中的重要性,透過筆記紀錄下使用方式。 ## 學習目標 了解`CancellationToken`的使用方式 ## 目錄 [TOC] # 介紹 其實`CancellationToken`從字面上就可以知道其用意,主要是用來針對任務進行取消用的,但實際上如何使用緊接著看下去。 ## 基本概念 進行講解之前先來認識一下`CancellationTokenSource`,這個東東主要用處是向`CancellationToken`發送訊號告知任務被取消了,所以算是啟動的源頭。 ## 使用說明 ### 手動取消任務 我們建立一個`CancellationTokenSource`將其產出的`Token`傳遞給我們所建立的`Task`,之後呼叫`Cancel()`執行取消的作業,代碼如下: ```csharp= var cts = new CancellationTokenSource(); _ = Execute(cts.Token); // 手動取消任務 cts.Cancel(); Console.WriteLine("Canceled"); Console.ReadKey(); async Task Execute(CancellationToken token) { await Task.Delay(1500, token); // 此處不會執行 Console.WriteLine("Executed"); } ``` 這邊可以看到因為我們取消了作業,因此"**Executed**"並沒有被輸出執行畫面 ![](https://i.imgur.com/YWEqqHH.png) ### 定時取消任務 我們在`CancellationTokenSource`建立時給予時間參數,任務會於等待指定的時間後自動取消任務。 ```csharp= // 加上時間,定時取消任務 var cts = new CancellationTokenSource(1000); _ = Execute(cts.Token); Console.WriteLine("Canceled"); Console.ReadKey(); async Task Execute(CancellationToken token) { await Task.Delay(1500, token); // 此處不會執行 Console.WriteLine("Executed"); } ``` 實作中我們給予一秒的等待時間後續也沒有呼叫取消作業(Cancel()),但"**Executed**"還是沒有被輸出,執行畫面如下: ![](https://i.imgur.com/Mjdp3nI.png) ## 註冊回呼 如果想要任務被取消後指定執行相關行為可以使用此方式,透過`CancellationToken`提供的[`Register(Action)`](https://docs.microsoft.com/zh-tw/dotnet/api/system.threading.cancellationtoken.register?view=net-6.0#system-threading-cancellationtoken-register(system-action))方法來註冊<font class="red">被取消後</font>執行的事情,如何使用直接看成是碼囉 ```csharp= var cts = new CancellationTokenSource(); // 註冊取消後行為 cts.Token.Register(() => { Console.WriteLine("Finish"); }); _ = Execute(cts.Token); // 手動取消 cts.Cancel(); Console.WriteLine("Canceled"); Console.ReadKey(); async Task Execute(CancellationToken token) { await Task.Delay(1500, token); // 此處不會執行 Console.WriteLine("Executed"); } ``` 這邊可以看到我們是使用手動取消去取消任務,當任務被取消後會去執行我們註冊的程序,就是把"**Finish**"輸出結果畫面如下: ![](https://i.imgur.com/9YIvJJU.png) # 結論 這邊的筆記幾乎都是從網路文章[在C#中使用 CancellationToken 處理非同步任務](https://iter01.com/590833.html)的分享,裡面後半段還有一些針對`HttpClient`和`WebAPI`使用上的測試,至於在這兩個情況下使用任務取消會發生什麼事,可以直接觀看其文章唷,這邊主要也是想整理成自己方便理解的筆記而已。 <br/> --- 相關參考來源: [在C#中使用 CancellationToken 處理非同步任務](https://iter01.com/590833.html) <style> .red{color: red;} </style>