日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > asp.net >内容正文

asp.net

.NET Core 取消令牌:CancellationToken

發(fā)布時(shí)間:2023/12/4 asp.net 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 .NET Core 取消令牌:CancellationToken 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

在 .NET 開(kāi)發(fā)中,CancellationToken(取消令牌)是一項(xiàng)比較重要的功能,掌握并合理的使用 CancellationToken 可以提升服務(wù)的性能。特別在異步編程中,我常常會(huì)以創(chuàng)建 Task 的方式利用多線程執(zhí)行一些耗時(shí)或非核心業(yè)務(wù)邏輯,表面上看既提高了整個(gè)流程的執(zhí)行速度,又充分利用了服務(wù)器資源。然而類似 Task 的方式如果沒(méi)設(shè)置過(guò)取消令牌,一旦開(kāi)啟,是無(wú)法被外部取消的,所以當(dāng)主線程出異常或被提前終止時(shí),已開(kāi)啟的異步線程其實(shí)依然在執(zhí)行,這時(shí)對(duì)服務(wù)器資源可能是一種浪費(fèi),而 CancellationToken 就可以對(duì)這類情況進(jìn)行一定的補(bǔ)救。

下面通過(guò)幾種常見(jiàn)的使用場(chǎng)景來(lái)介紹 CancellationToken。

在 HttpClient 中的使用

HttpClient 是開(kāi)發(fā)中比較常用的一個(gè)組件,關(guān)于超時(shí)可通過(guò) Timeout 參數(shù)進(jìn)行設(shè)置,其實(shí)它也是可以通過(guò)配置 CancellationToken 來(lái)實(shí)現(xiàn)超時(shí)定義,使用 CancellationToken 的最大好處是調(diào)用鏈共享此令牌狀態(tài),狀態(tài)變更時(shí)會(huì)自動(dòng)做出響應(yīng)。

public async Task<string> GetHomeAsync(CancellationToken cancellationToken = default) {var client = _httpClientFactory.CreateClient();var response = await client.GetAsync("https://github.com/", cancellationToken);response.EnsureSuccessStatusCode();return await response.Content.ReadAsStringAsync(); } public async Task<string> GetGithubHome() {var cts = new CancellationTokenSource(1000);var result = await _githubService.GetHomeAsync(cts.Token);return result; }

Github 一般訪問(wèn)會(huì)比較慢,可通過(guò)設(shè)置 1s 演示效果:

在 gRPC 中的使用

通過(guò) VS 的 gRPC 服務(wù)模板創(chuàng)建一個(gè) gRPC 服務(wù)端(如果對(duì) gRPC 的使用還不太了解,參考官方文檔[1] 玩起來(lái)吧),服務(wù)端主要提供一個(gè)獲取用戶列表 (GetList) 的接口。實(shí)現(xiàn)如下,_userRepository 內(nèi)部是基于 MongoDB 實(shí)現(xiàn)的查詢用戶數(shù)據(jù),對(duì)應(yīng)使用的 MongoDB.Driver 提供的方法默認(rèn)已支持設(shè)置 CancellationToken,所以這里直接引用 ServerCallContext ?上下文中的 CancellationToken,而此 CancellationToken 又是從客戶端傳遞來(lái)的,所以 CancellationToken ?將作用于整個(gè)調(diào)用鏈中。另外如果在客戶端動(dòng)態(tài)取消了此令牌,服務(wù)器也將會(huì)收到通知。

public override async Task<GetListReply> GetList(GetListRequest request, ServerCallContext context) {await Task.Delay(1000); // 模擬效果,服務(wù)端停1svar users = await _userRepository.GetListAsync(context.CancellationToken);var reply = new GetListReply();foreach (var item in users){reply.Users.Add(new UserModel { UserId = item.UserId, Name = item.Name });}return reply; }

Client 端主要代碼如下,在接口層創(chuàng)建了 CancellationTokenSource 對(duì)象,并設(shè)置了令牌的過(guò)期時(shí)間,即在發(fā)起遠(yuǎn)程調(diào)用時(shí),如果 1s 內(nèi)沒(méi)返回,那就取消這個(gè)調(diào)用。

public class UserService : IUserService {private readonly UserClient _client;public UserService(){var channel = GrpcChannel.ForAddress("https://localhost:5001");_client = new UserClient(channel);}public async Task<GetListReply> GetListAsync(CancellationToken cancellationToken = default){return await _client.GetListAsync(new GetListRequest(), cancellationToken: cts.Token);} } [HttpGet] public async Task<string> GetUserList() {var cts = new CancellationTokenSource(1000);var result = await _userService.GetListAsync(cts.Token);return JsonConvert.SerializeObject(result.Users); }

在 WebAPI 中的使用

前端調(diào)用后端的接口一般是基于 Ajax 來(lái)實(shí)現(xiàn),當(dāng)瀏覽器網(wǎng)頁(yè)被 連續(xù) F5 刷新頁(yè)面加載中被停止Ajax 請(qǐng)求被主動(dòng) abort 時(shí),控制臺(tái) network 看板中會(huì)出現(xiàn)一些狀態(tài)為 canceled 的請(qǐng)求,如下:

對(duì)于這類請(qǐng)求,客戶端雖然主動(dòng)放棄了,如果服務(wù)端沒(méi)有相應(yīng)處理,其實(shí)接口對(duì)應(yīng)的后端程序還是在不停的執(zhí)行,只是這個(gè)執(zhí)行結(jié)果不會(huì)被使用而已,所以這其實(shí)是非常浪費(fèi)服務(wù)器資源的。

實(shí)際上瀏覽器取消請(qǐng)求時(shí),服務(wù)端會(huì)將 HttpContext.RequestAborted 中的 Token 綁定到 Action 的 CancellationToken 參數(shù)。我們只需在接口中增加參數(shù) CancellationToken,并將其傳入其他接口調(diào)用中,程序識(shí)別到令牌被取消就會(huì)自動(dòng)放棄繼續(xù)執(zhí)行。

[HttpGet] public async Task<string> Index(CancellationToken cancellationToken) {try{await _userService.GetListAsync(cancellationToken);await Task.Delay(5000); // 等待期間,取消請(qǐng)求(Postman 即可模擬)await _githubService.GetHomeAsync(cancellationToken);}catch (Exception ex){Console.WriteLine(ex.Message + Environment.NewLine + ex.StackTrace);}return "ok"; }

對(duì)于 WebAPI ?接口被取消調(diào)用的場(chǎng)景,特別是對(duì)于查詢功能的接口,CancellationToken 的傳遞就顯得尤為必要了,它能減少很多底層服務(wù)接口的無(wú)效調(diào)用。

最后針對(duì)取消令牌產(chǎn)生的異常需要收尾干凈,一般像 WebAPI 項(xiàng)目可以使用自帶的過(guò)濾器或具有 AOP 功能的組件,gRPC 服務(wù)可使用自帶的攔截器功能。

總結(jié)

以上是生活随笔為你收集整理的.NET Core 取消令牌:CancellationToken的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: a级片一区二区 | 日韩免费中文字幕 | 激情网婷婷| 国产八区 | 一区三区在线观看 | av午夜激情 | 国产精品麻豆成人av电影艾秋 | 日韩电影在线一区二区 | av永久免费在线观看 | 超碰影院在线 | 在线aa | a级片视频网站 | 俺来也在线视频 | 色偷偷免费费视频在线 | 中文字幕11页中文字幕11页 | 日韩a视频| 91尤物国产福利在线观看 | 精品国产丝袜一区二区三区乱码 | 亚洲综合99 | 亚洲精品男人的天堂 | 国产精品一二三四区 | 大尺度舌吻呻吟声 | www.在线观看av | 日本精品99 | 久久综合色视频 | www.久色| 正在播放老肥熟妇露脸 | 自拍偷拍色综合 | 国产精品永久免费视频 | av手机版 | 北条麻妃一区二区三区在线观看 | 五月婷婷开心网 | 免费插插视频 | 老司机激情影院 | 亚洲第一区在线观看 | 精品久久精品久久 | 久久久噜噜噜久久中文字幕色伊伊 | 五月婷婷激情综合网 | 欧美一区二区三区观看 | 日韩成人av在线 | 日韩电影网站 | 91高清国产 | 亚洲免费a | 亚洲涩综合 | 青青操视频在线播放 | 欧美在线国产 | 国外成人性视频免费 | 我要看一级片 | 国产黄片毛片 | 香港一级淫片免费放 | 中文在线а√天堂官网 | 国产精品日本一区二区在线播放 | 在线免费精品视频 | 中文字幕亚洲第一 | 久久久久久片 | 亚洲永久精品在线观看 | av作品在线观看 | 亚洲无人区小视频 | 国产精品久久久午夜夜伦鲁鲁 | 男女猛烈无遮挡免费视频 | 蜜臀av性久久久久蜜臀aⅴ流畅 | 人人妻人人澡人人爽人人精品 | 热久久91 | 日韩精品一区二区在线观看 | 青青免费在线视频 | 亚洲免费福利视频 | 一级特黄av | 日b视频在线观看 | 91视频论坛| 亚洲视频一二三四 | 伦理片波多野结衣 | 日本成片网 | 婷婷在线免费 | 国内精品卡一卡二卡三 | 日本久久综合网 | 天天爽av | 宅男av在线| 在线不卡日韩 | 国产在线视频一区二区三区 | 亚洲一区二区黄片 | 色婷婷久久久亚洲一区二区三区 | 天天爽夜夜爽夜夜爽精品视频 | 五月在线 | 国产激情久久久 | 东方av在线播放 | 成人av播放 | 五月婷婷,六月丁香 | 三级无遮挡 | 一曲二曲三曲在线观看中文字幕动漫 | 公肉吊粗大爽色翁浪妇视频 | 欧美日韩高清丝袜 | 青青成人在线 | 欧美大喷水吹潮合集在线观看 | 天天综合91| 日韩三级一区 | 用舌头去添高潮无码视频 | 麻豆福利视频 | 久久国内精品视频 | 香蕉网久久 |