您好,登錄后才能下訂單哦!
今天就跟大家聊聊有關AspNetCore應用注意哪些點,可能很多人都不太了解,為了讓大家更加了解,小編給大家總結了以下內容,希望大家根據這篇文章可以有所收獲。
背景
已經有很多文章記錄了Web程序中采用異步編程的優勢和.Net異步編程的用法, 異步編程雖然不能解決查詢數據庫的瓶頸, 但是利用線程切換,能最大限度的彈性利用工作線程, 提高了web服務的響應能力。
這里要說的是利用異步編程中的取消機制緩解數據庫的查詢瓶頸,開發者只需在MVC/WebAPI查詢方法。
CancellationToken并適時取消異步任務, 這將大大提高應用的響應能力。
頭腦風暴
想象你請求某網站頁面,該頁面正閃著菊花試圖努力綻放(正在加載),最終你忍不了:
① F5刷新
② 轉向其他頁面
③ 點擊瀏覽器“停止”按鈕
對于Web服務器,用戶快速刷新5次,服務器將被迫接受 5倍的工作量,這是因為即使用戶刷新了瀏覽器(或點擊停止按鈕), 雖然取消了原始瀏覽器請求,但是Web服務器并不Care,仍然按部就班處理進入HTTP pipeline的請求(MVC/WebAPI 中默認行為,②③場景類似)
在異步編程中能向任務發出Cancellation信號,停止web服務器后端查詢行為。在.NET中,這是使用CancellationToken完成的:
取消令牌的實例傳遞到異步任務
異步任務監視令牌,以查看請求是否已經被取消。
如果請求取消,則應停止執行正在執行的操作。.NET中的大多數異步方法將具有接受取消令牌的重載。
tip
本文取消的請求,指的是耗時長的服務端讀取請求(返回數據但不修改數據的查詢),取消已修改數據的請求對于用程序可能不是一個好的選擇:
① 是否真的要因為用戶導航到應用的另一個頁面而取消保存?也許可以,但也可能不會。
② 提高了復雜性,因為數據庫服務器可能需要回滾事務,這是一項昂貴的操作。
AspNetCore實踐
訪問MyReallySlowReport頁面,等待5s,最終他們放棄去了其他頁面:
所有正在進行的請求都將被取消。
P1 監測CancellationToken令牌
MVC/WebAPI能收到取消請求的信號。開發者只需要在Controller Action中添加CancellationToken參數,并在后續行為中監測該取消信號。
public async Task<ActionResult> MyReallySlowReport(CancellationToken cancellationToken)
{
List<ReportItem> items;
using (ApplicationDbContext context = new ApplicationDbContext())
{
items = await context.ReportItems.ToListAsync(cancellationToken);
}
return View(items);
}
上述EF的調用api支持取消異步操作,故很容易取消SQL的查詢行為;對于自定義的長耗時查詢行為,可以使用CancellationToken的原生觸發用法:
public async Task<ActionResult> MyReallySlowReport(CancellationToken cancellationToken)
{
List<ReportItem> items;
using (ApplicationDbContext context = new ApplicationDbContext())
{
items = await context.ReportItems.ToListAsync(cancellationToken);
}
foreach (var item in items)
{
cancellationToken.ThrowIfCancellationRequested();
// slow non-cancellable work
Thread.Sleep(1000);
}
return View(items);
}
P2 處理取消異步操作向上拋出的異常處
Web服務器觸發取消信號,一般會向上會拋出OperationCanceledException或TaskCancellationException,所以為了記錄這種非常規異常,建議采用獨立的ExceptionFilter。
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);
}
}
}
P3 想要得到CTO的大拇指,繼續思考吧
以上是后端程序員利用取消機制緩解異步查詢瓶頸的操作,從web應用全流程角度思考,這個優化還能提升嗎? ????
> 以上是傳統的網頁請求場景,在取消請求時,瀏覽器幫助我們發起了Cancellation信號。
> 想想日益常見的SPA程序(單頁面程序),絕大部分頁面請求都是Ajax請求,你點擊應用的另外一個“頁面”(JS代碼維護頁面導航),瀏覽器不會自動取消請求。所以在SPA應用中要前端自己發出取消請求的信號:
var xhr = $.get("/api/myslowreport", function(data){
//show the data
});
//If the user navigates away from this page
xhr.abort()
前后端程序猿通力配合,應用的吞吐量和響應能力極大提升,CTO要給各位加薪了。
看完上述內容,你們對AspNetCore應用注意哪些點有進一步的了解嗎?如果還想了解更多知識或者相關內容,請關注億速云行業資訊頻道,感謝大家的支持。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。