.NET?Core使用?CancellationToken?取消API請(qǐng)求的操作方法
您是否曾經(jīng)訪問(wèn)過(guò)一個(gè)網(wǎng)站,它需要很長(zhǎng)時(shí)間加載,最終你敲擊 F5 重新加載頁(yè)面。
即使用戶(hù)刷新了瀏覽器取消了原始請(qǐng)求,而對(duì)于服務(wù)器來(lái)說(shuō),API也不會(huì)知道它正在計(jì)算的值將在結(jié)束時(shí)被丟棄,刷新五次,服務(wù)器將觸發(fā) 5 個(gè)請(qǐng)求。
為了解決這個(gè)問(wèn)題,ASP.NET Core 為 Web 服務(wù)器提供了一種機(jī)制,就是CancellationToken.
用戶(hù)取消請(qǐng)求時(shí),你可以使用HttpContext.RequestAborted訪問(wèn),您也可以使用依賴(lài)注入將其自動(dòng)注入到您的操作中。
長(zhǎng)時(shí)間運(yùn)行的任務(wù)請(qǐng)求
現(xiàn)在我們假設(shè)您有一個(gè) API 操作,在向用戶(hù)發(fā)送響應(yīng)之前可能需要一些時(shí)間才能完成。
在處理該操作時(shí),用戶(hù)可以直接取消請(qǐng)求,或刷新頁(yè)面(這會(huì)有效地取消原始請(qǐng)求,并啟動(dòng)新請(qǐng)求)。
[HttpGet(Name = "get")] public async Task<string> GetAsync() { try { _logger.LogInformation("request in"); await Task.Delay(5 * 1000); _logger.LogInformation("request end"); } catch (Exception ex) { _logger.LogInformation("request ex"); } return "ok"; }
如果用戶(hù)在請(qǐng)求中途刷新瀏覽器,那么瀏覽器永遠(yuǎn)不會(huì)收到第一個(gè)請(qǐng)求的響應(yīng),但在server端可以看到,操作方法執(zhí)行完成兩次。
這是否是正確將取決于您的應(yīng)用程序。
如果請(qǐng)求修改某些業(yè)務(wù)的狀態(tài),那么您可能不希望在方法中途停止執(zhí)行。如果請(qǐng)求沒(méi)有副作用,那么您可能希望盡快停止(可能很昂貴)操作。
用戶(hù)取消請(qǐng)求時(shí),你可以使用HttpContext.RequestAborted訪問(wèn),您也可以使用依賴(lài)注入將其自動(dòng)注入到您的操作中。
CancellationTokens取消不必要的請(qǐng)求
以下代碼顯示了如何通過(guò)將CancellationTokenSource 注入到操作方法中,并通過(guò)其取消不必要的操作。
[HttpGet(Name = "get")] public async Task<string> GetAsync(CancellationToken cancellationToken) { try { _logger.LogInformation("request in"); await Task.Delay(5 * 1000,cancellationToken); _logger.LogInformation("request end"); } catch (Exception ex) { _logger.LogInformation("request ex"); } return "ok"; }
通過(guò)這個(gè)改變,我們可以再次測(cè)試我們的場(chǎng)景。
我們發(fā)出一個(gè)初始請(qǐng)求,然后我們重新加載頁(yè)面。正如您從下面的日志中看到的,第一個(gè)請(qǐng)求不會(huì)繼續(xù)執(zhí)行。
用戶(hù)刷新瀏覽器取消請(qǐng)求后不久,原始請(qǐng)求就會(huì)中止,并TaskCancelledException通過(guò) API 過(guò)濾器管道傳播回來(lái),并備份中間件管道。
根據(jù)您的場(chǎng)景,您可能能夠依靠此類(lèi)框架方法來(lái)檢查 的狀態(tài)CancellationToken,或者您可能需要自己監(jiān)視取消請(qǐng)求。
過(guò)濾器捕獲異常
您可以通過(guò)以上try catch 捕獲,或者通過(guò)一個(gè)過(guò)濾器統(tǒng)一監(jiān)視此異常。
public class OperationCancelledExceptionFilter : ExceptionFilterAttribute { private readonly ILogger _logger; public OperationCancelledExceptionFilter(ILoggerFactory loggerFactory) { _logger = loggerFactory.CreateLogger<OperationCancelledExceptionFilter>(); } public override void OnException(ExceptionContext context) { if (context.Exception is OperationCanceledException) { _logger.LogInformation("Request was cancelled"); context.ExceptionHandled = true; context.Result = new StatusCodeResult(400); } } } builder.Services.AddControllers(options => { options.Filters.Add<OperationCancelledExceptionFilter>(); });
到此這篇關(guān)于.NET Core使用 CancellationToken 取消API請(qǐng)求的文章就介紹到這了,更多相關(guān).NET Core取消API請(qǐng)求內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
.NET core 3.0如何使用Jwt保護(hù)api詳解
這篇文章主要給大家介紹了關(guān)于.NET core 3.0如何使用Jwt保護(hù)api的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用.NET core 3.0具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-11-11ASP.NET URL偽靜態(tài)重寫(xiě)實(shí)現(xiàn)方法
ASP.NET下為靜態(tài)的實(shí)現(xiàn)方法。2009-12-12DataGrid中實(shí)現(xiàn)超鏈接的3種方法
這篇文章介紹了DataGrid中實(shí)現(xiàn)超鏈接的3種方法,有需要的朋友可以參考一下2013-09-09點(diǎn)擊圖片,AJAX刪除后臺(tái)圖片文件的實(shí)現(xiàn)代碼(asp.net)
點(diǎn)擊頁(yè)面上的圖片,用jQuery的AJAX來(lái)刪除后臺(tái)真實(shí)的文件。2010-11-11詳解ASP.NET MVC 利用Razor引擎生成靜態(tài)頁(yè)
本篇文章主要介紹了ASP.NET MVC 利用Razor引擎生成靜態(tài)頁(yè),詳細(xì)的介紹了原理和步驟,具有一定的參考價(jià)值,有興趣的可以了解一下。2017-03-03gridview和checkboxlist的嵌套相關(guān)應(yīng)用
gridview和checkboxlist的嵌套使用,會(huì)有效的提高開(kāi)發(fā)的效率,不過(guò)很多的童鞋們對(duì)此還是很陌生的,接下來(lái)將幫助童鞋們實(shí)現(xiàn)gridview和checkboxlist的嵌套使用,感興趣的朋友可以了解下,或許對(duì)你有所幫助2013-02-02ASP.NET對(duì)HTML頁(yè)面元素進(jìn)行權(quán)限控制(一)
界面每個(gè)元素的權(quán)限也是需要控制的。比如一個(gè)查詢(xún)用戶(hù)的界面里面有查詢(xún)用戶(hù)按鈕,添加用戶(hù)按鈕,刪除用戶(hù)按鈕,不同的角色我們得分配不同的權(quán)限2013-12-12