C# CancellationToken的使用小結(jié)
在 C# 中,CancellationToken 是用于實(shí)現(xiàn) 協(xié)作式取消(Cooperative Cancellation) 的核心類型,主要應(yīng)用于異步操作、多線程任務(wù)或長(zhǎng)時(shí)間運(yùn)行的任務(wù)。以下是詳細(xì)的講解:
1. 核心概念
- 作用:允許一個(gè)任務(wù)/操作在外部被請(qǐng)求取消,任務(wù)自身會(huì)定期檢查是否被取消請(qǐng)求,實(shí)現(xiàn)優(yōu)雅終止。
- 協(xié)作式:任務(wù)需要主動(dòng)配合檢查取消請(qǐng)求(不能強(qiáng)行終止線程)。
- 組成:
CancellationTokenSource:生成和管理CancellationToken的類。CancellationToken:傳遞給任務(wù)的結(jié)構(gòu)體,用于傳遞“取消信號(hào)”。
2. 基本用法
步驟 1:創(chuàng)建 CancellationTokenSource 和 Token
var cts = new CancellationTokenSource(); CancellationToken token = cts.Token;
步驟 2:將 Token 傳遞給任務(wù)
Task.Run(() =>
{
// 任務(wù)邏輯
}, token);
步驟 3:觸發(fā)取消
cts.Cancel(); // 請(qǐng)求取消所有關(guān)聯(lián) Token 的任務(wù)
3. 在任務(wù)中處理取消
輪詢檢查 Token
public void LongRunningOperation(CancellationToken token)
{
while (!token.IsCancellationRequested)
{
// 持續(xù)工作...
Thread.Sleep(1000);
}
// 清理資源,優(yōu)雅退出
Console.WriteLine("操作被取消。");
}
拋出取消異常
當(dāng)需要直接終止操作時(shí),可以通過(guò)拋出 OperationCanceledException 來(lái)快速響應(yīng)取消請(qǐng)求:
token.ThrowIfCancellationRequested(); // 如果取消已請(qǐng)求,拋出異常
4. 高級(jí)特性
注冊(cè)取消回調(diào)
當(dāng)取消被觸發(fā)時(shí),執(zhí)行指定的回調(diào)函數(shù)(如釋放資源):
token.Register(() =>
{
Console.WriteLine("清理資源,取消已觸發(fā)!");
});
超時(shí)自動(dòng)取消
利用 CancellationTokenSource 設(shè)置超時(shí)時(shí)間,自動(dòng)觸發(fā)取消:
var cts = new CancellationTokenSource(TimeSpan.FromSeconds(5)); // 5秒后自動(dòng)取消
組合 Token(鏈接)
將多個(gè) CancellationToken 組合成一個(gè),任一觸發(fā)則全部取消:
var linkedCts = CancellationTokenSource.CreateLinkedTokenSource(token1, token2); var linkedToken = linkedCts.Token;
5. 異常處理
取消操作通常會(huì)引發(fā)兩種異常:
OperationCanceledExceptionTaskCanceledException(繼承自前者)
示例:
try
{
await SomeAsyncMethod(token);
}
catch (OperationCanceledException)
{
Console.WriteLine("操作已被取消。");
}
6. 最佳實(shí)踐
- 及時(shí)傳遞 Token:將
CancellationToken傳遞給所有需要支持取消的方法。 - 避免阻塞操作:在非異步代碼中定期檢查
IsCancellationRequested。 - 正確處理異常:不濫用
try-catch忽略取消異常。 - 釋放資源:確保在取消后清理打開(kāi)的資源(如文件句柄、網(wǎng)絡(luò)連接)。
7. 使用場(chǎng)景
- 用戶取消操作(如界面上的“取消”按鈕)。
- 服務(wù)限時(shí)處理(例如 API 請(qǐng)求超時(shí))。
- 后臺(tái)任務(wù)管理(如 ASP.NET Core 中請(qǐng)求中止處理)。
- 并行任務(wù)控制(取消一組相關(guān)任務(wù))。
8. 完整示例
var cts = new CancellationTokenSource();
var token = cts.Token;
// 啟動(dòng)任務(wù)
var task = Task.Run(() =>
{
try
{
while (true)
{
token.ThrowIfCancellationRequested();
Console.WriteLine("工作...");
Thread.Sleep(1000);
}
}
catch (OperationCanceledException)
{
Console.WriteLine("任務(wù)取消。");
}
});
// 例如:用戶按下取消按鈕,或者超時(shí)自動(dòng)取消
Thread.Sleep(3000);
cts.Cancel();
9. 注意事項(xiàng)
- 線程安全:
CancellationToken是一個(gè)只讀結(jié)構(gòu)體,本身線程安全。 - 資源釋放:
CancellationTokenSource實(shí)現(xiàn)了IDisposable,長(zhǎng)時(shí)間不使用時(shí)需釋放。 - 不可復(fù)用:一旦取消,Token 無(wú)法重新激活,需創(chuàng)建新的
CancellationTokenSource。
到此這篇關(guān)于C# CancellationToken的使用小結(jié)的文章就介紹到這了,更多相關(guān)C# CancellationToken使用內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C#實(shí)現(xiàn)ComboBox自動(dòng)匹配字符
本文介紹C#如何實(shí)現(xiàn)ComboBox自動(dòng)匹配字符1.采用CustomSource當(dāng)做提示集合2. 直接使用下拉列表中的項(xiàng)作為匹配的集合,需要了解的朋友可以參考下2012-12-12
C#后臺(tái)調(diào)用前臺(tái)JS函數(shù)方法
今天小編就為大家分享一篇關(guān)于C#后臺(tái)調(diào)用前臺(tái)JS函數(shù)方法,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧2019-01-01
C#判斷一個(gè)字符串是否包含另一個(gè)字符串的方法
這篇文章主要介紹了C#判斷一個(gè)字符串是否包含另一個(gè)字符串的方法,涉及C#中IndexOf方法的使用技巧,非常簡(jiǎn)單實(shí)用,需要的朋友可以參考下2015-04-04
C#針對(duì)System.Drawing.Bitmap壓縮的實(shí)現(xiàn)
C#中System.Drawing.Bitmap壓縮可通過(guò)調(diào)整尺寸和JPEG質(zhì)量實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2025-07-07
C#單例模式Singleton的實(shí)現(xiàn)詳解
單例模式(Singleton?Pattern)是日常開(kāi)發(fā)中最簡(jiǎn)單的設(shè)計(jì)模式之一,它提供了一種創(chuàng)建對(duì)象的最佳方式,本文主要為大家介紹的是C#單例模式的實(shí)現(xiàn)方法,需要的可以參考一下2023-05-05
Unity實(shí)現(xiàn)簡(jiǎn)單虛擬搖桿
這篇文章主要為大家詳細(xì)介紹了Unity實(shí)現(xiàn)簡(jiǎn)單虛擬搖桿,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-04-04
基于C#的UDP協(xié)議的同步通信實(shí)現(xiàn)代碼
本篇文章主要介紹了基于C#的UDP協(xié)議的同步實(shí)現(xiàn)代碼,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-02-02
C#如何將List<string>轉(zhuǎn)換為L(zhǎng)ist<double>
這篇文章主要介紹了C#如何將List<string>轉(zhuǎn)換為L(zhǎng)ist<double>問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-07-07
C# WinForm程序設(shè)計(jì)簡(jiǎn)單計(jì)算器
這篇文章主要為大家詳細(xì)介紹了C# WinForm程序設(shè)計(jì)簡(jiǎn)單計(jì)算器,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-02-02

