# 關於 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**"並沒有被輸出執行畫面

### 定時取消任務
我們在`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**"還是沒有被輸出,執行畫面如下:

## 註冊回呼
如果想要任務被取消後指定執行相關行為可以使用此方式,透過`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**"輸出結果畫面如下:

# 結論
這邊的筆記幾乎都是從網路文章[在C#中使用 CancellationToken 處理非同步任務](https://iter01.com/590833.html)的分享,裡面後半段還有一些針對`HttpClient`和`WebAPI`使用上的測試,至於在這兩個情況下使用任務取消會發生什麼事,可以直接觀看其文章唷,這邊主要也是想整理成自己方便理解的筆記而已。
<br/>
---
相關參考來源:
[在C#中使用 CancellationToken 處理非同步任務](https://iter01.com/590833.html)
<style>
.red{color: red;}
</style>