.NET Core使用 CancellationToken 取消API请求
您是否曾经访问过一个网站,它需要很长时间加载,最终你敲击 F5 重新加载页面。
即使用户刷新了浏览器取消了原始请求,而对于服务器来说,API也不会知道它正在计算的值将在结束时被丢弃,刷新五次,服务器将触发 5 个请求。
为了解决这个问题,ASP.NET Core 为 Web 服务器提供了一种机制,就是CancellationToken.
用户取消请求时,你可以使用HttpContext.RequestAborted访问,您也可以使用依赖注入将其自动注入到您的操作中。
长时间运行的任务请求
现在我们假设您有一个 API 操作,在向用户发送响应之前可能需要一些时间才能完成。
在处理该操作时,用户可以直接取消请求,或刷新页面(这会有效地取消原始请求,并启动新请求)。
[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";
}
如果用户在请求中途刷新浏览器,那么浏览器永远不会收到第一个请求的响应,但在server端可以看到,操作方法执行完成两次。
这是否是正确将取决于您的应用程序。
如果请求修改某些业务的状态,那么您可能不希望在方法中途停止执行。如果请求没有副作用,那么您可能希望尽快停止(可能很昂贵)操作。
用户取消请求时,你可以使用HttpContext.RequestAborted访问,您也可以使用依赖注入将其自动注入到您的操作中。
CancellationTokens取消不必要的请求
以下代码显示了如何通过将 CancellationTokenSource 注入到操作方法中,并通过其取消不必要的操作。
[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";
}
通过这个改变,我们可以再次测试我们的场景。
我们发出一个初始请求,然后我们重新加载页面。正如您从下面的日志中看到的,第一个请求不会继续执行。
用户刷新浏览器取消请求后不久,原始请求就会中止,并TaskCancelledException通过 API 过滤器管道传播回来,并备份中间件管道。
根据您的场景,您可能能够依靠此类框架方法来检查 的状态CancellationToken,或者您可能需要自己监视取消请求。
过滤器捕获异常
您可以通过以上try catch 捕获,或者通过一个过滤器统一监视此异常。
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>();
});
.NET Core使用 CancellationToken 取消API请求的更多相关文章
- 在ASP.NET Core中用HttpClient(五)——通过CancellationToken取消HTTP请求
用户向服务器发送HTTP请求应用程序页面是一种非常可能的情况.当我们的应用程序处理请求时,用户可以从该页面离开.在这种情况下,我们希望取消HTTP请求,因为响应对该用户不再重要.当然,这只是实际应用 ...
- 如何测量并报告ASP.NET Core Web API请求的响应时间
介绍 大家都知道性能是API的流行语.而相应时间则是API性能的一个重要并且可测量的参数.在本文中,我们将了解如何使用代码来测量API的响应时间,然后将响应时间数据返回到客户端. 作者:依乐祝 原文地 ...
- ASP.NET实现二维码 ASP.Net上传文件 SQL基础语法 C# 动态创建数据库三(MySQL) Net Core 实现谷歌翻译ApI 免费版 C#发布和调试WebService ajax调用WebService实现数据库操作 C# 实体类转json数据过滤掉字段为null的字段
ASP.NET实现二维码 using System;using System.Collections.Generic;using System.Drawing;using System.Linq;us ...
- 从头编写 asp.net core 2.0 web api 基础框架 (1)
工具: 1.Visual Studio 2017 V15.3.5+ 2.Postman (Chrome的App) 3.Chrome (最好是) 关于.net core或者.net core 2.0的相 ...
- 从头编写 asp.net core 2.0 web api 基础框架 (3)
第一部分:http://www.cnblogs.com/cgzl/p/7637250.html 第二部分:http://www.cnblogs.com/cgzl/p/7640077.html 之前我介 ...
- 【转载】从头编写 asp.net core 2.0 web api 基础框架 (3)
Github源码地址:https://github.com/solenovex/Building-asp.net-core-2-web-api-starter-template-from-scratc ...
- 【转载】从头编写 asp.net core 2.0 web api 基础框架 (1)
工具: 1.Visual Studio 2017 V15.3.5+ 2.Postman (Chrome的App) 3.Chrome (最好是) 关于.net core或者.net core 2.0的相 ...
- ASP.NET Core Razor中处理Ajax请求
如何ASP.NET Core Razor中处理Ajax请求 在ASP.NET Core Razor(以下简称Razor)刚出来的时候,看了一下官方的文档,一直没怎么用过.今天闲来无事,准备用Rozor ...
- 使用 ASP.NET Core MVC 创建 Web API(五)
使用 ASP.NET Core MVC 创建 Web API 使用 ASP.NET Core MVC 创建 Web API(一) 使用 ASP.NET Core MVC 创建 Web API(二) 使 ...
- 使用 ASP.NET Core MVC 创建 Web API(一)
从今天开始来学习如何在 ASP.NET Core 中构建 Web API 以及每项功能的最佳适用场景.关于此次示例的数据库创建请参考<学习ASP.NET Core Razor 编程系列一> ...
随机推荐
- Mac 上 redis 的安装方法
1.由于需要用到编译,所以先安装xcode,注意利用appstore安装xcode后,记得打开xcode 点install,也可以建立一个macos项目,运行下 试下. 2. 去官网下载:https: ...
- 基于Microsoft SemanticKernel和GPT4实现一个智能翻译服务
今年.NET Conf China 2023技术大会,我给大家分享了 .NET应用国际化-AIGC智能翻译+代码生成的议题 .NET Conf China 2023分享-.NET应用国际化-AIGC智 ...
- AT_abc270_g [ABC270G] Sequence in mod P 题解
题目传送门 前置知识 大步小步算法 解法 递推式为 \(x_{n}=(ax_{n-1}+b) \bmod p\),发现可以统一消去 \(\bmod p\) ,只在最后参与计算.以下过程省去模运算. 当 ...
- NC235745 拆路
题目链接 题目 题目描述 有 \(n\) 个城镇,城镇之间有 \(m\) 条道路相连,道路可以看成无向边.每一个城镇都有自己的一个繁荣度 \(v_i\) ,一个城镇 \(u\) 受到的影响 \(p\) ...
- 轻松玩转makefile | 变量与模式
前言 本文通过简单的几个示例,以及对同一个Makefile进行几个版本的迭代,帮助快速的理解变量和模式规则的使用. 1.回顾 在上一篇文章中,我们使用Makefile编译fun.c和main.c这两个 ...
- 从零开始手写缓存框架(二)redis expire 过期原理及实现
前言 我们在 从零手写 cache 框架(一)实现固定大小的缓存 中已经初步实现了我们的 cache. 本节,让我们来一起学习一下如何实现类似 redis 中的 expire 过期功能. 过期是一个非 ...
- ElementUI导入Excel文件
功能介绍 最近用ElementUI做管理系统需要把excel数据导入到系统内,我想这是一个很常见的功能点,把它分享出来,希望对大家有所帮助:) 实现效果 实现步骤 1.定义导入组件 <el-up ...
- js常用知识点整理
说明:以下内容都是我工作中实际碰到的js知识点. 后面还会碰到其他知识点或对原来解决方案的改进,都会在本篇中持续不断的维护,希望给刚参加工作或初学的朋友一些参考. 1.给元素添加事件 $(" ...
- centos7下修改mysql5.5字符集
1.查看现有数据库编码 show variables like "%char%"; 2.修改mysql配置文件:/etc/my.cnf(以实际安装环境为准) 在[client]字段 ...
- C++ 多线程的错误和如何避免(6)
加锁的临界区要尽可能的紧凑和小型 问题分析: 当一个线程在临界区内执行时,所有其他试图进入临界区的线程都会被阻止,所以我们应该保证临界区尽可能的小.比如, void CallHome(string m ...