您是否曾经访问过一个网站,它需要很长时间加载,最终你敲击 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请求的更多相关文章

  1. 在ASP.NET Core中用HttpClient(五)——通过CancellationToken取消HTTP请求

    ​用户向服务器发送HTTP请求应用程序页面是一种非常可能的情况.当我们的应用程序处理请求时,用户可以从该页面离开.在这种情况下,我们希望取消HTTP请求,因为响应对该用户不再重要.当然,这只是实际应用 ...

  2. 如何测量并报告ASP.NET Core Web API请求的响应时间

    介绍 大家都知道性能是API的流行语.而相应时间则是API性能的一个重要并且可测量的参数.在本文中,我们将了解如何使用代码来测量API的响应时间,然后将响应时间数据返回到客户端. 作者:依乐祝 原文地 ...

  3. 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 ...

  4. 从头编写 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的相 ...

  5. 从头编写 asp.net core 2.0 web api 基础框架 (3)

    第一部分:http://www.cnblogs.com/cgzl/p/7637250.html 第二部分:http://www.cnblogs.com/cgzl/p/7640077.html 之前我介 ...

  6. 【转载】从头编写 asp.net core 2.0 web api 基础框架 (3)

    Github源码地址:https://github.com/solenovex/Building-asp.net-core-2-web-api-starter-template-from-scratc ...

  7. 【转载】从头编写 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的相 ...

  8. ASP.NET Core Razor中处理Ajax请求

    如何ASP.NET Core Razor中处理Ajax请求 在ASP.NET Core Razor(以下简称Razor)刚出来的时候,看了一下官方的文档,一直没怎么用过.今天闲来无事,准备用Rozor ...

  9. 使用 ASP.NET Core MVC 创建 Web API(五)

    使用 ASP.NET Core MVC 创建 Web API 使用 ASP.NET Core MVC 创建 Web API(一) 使用 ASP.NET Core MVC 创建 Web API(二) 使 ...

  10. 使用 ASP.NET Core MVC 创建 Web API(一)

    从今天开始来学习如何在 ASP.NET Core 中构建 Web API 以及每项功能的最佳适用场景.关于此次示例的数据库创建请参考<学习ASP.NET Core Razor 编程系列一> ...

随机推荐

  1. Java 数字 默认是 Integer类型的问题,System.currentTimeMillis() + (180 * 24 * 60 * 60 * 1000)的问题,剖析、Long + Integer的问题

    最终结论: (180 * 24 * 60 * 60) 这种计算表达式在 Java中是默认以 Integer类型来的,若不超过 Integer的最大值则没有问题,若超过则必须用 (180 * 24 * ...

  2. Centos8 单机配置 Zookeeper3.6.3 集群

    安装 Zookeeper 3.6.3 前提 已经安装好 JDK8+. 如果使用JDK8, 版本需要在211以上. 下载, 解压 使用root用户 wget https://downloads.apac ...

  3. Java语法专题3: HashMap

    合集目录 Java语法专题3: HashMap 谈谈 HashMap 的特性 存储KV键值对, 实现快速存取, key和value都允许为null. key值唯一, 重复则覆盖. key为null时, ...

  4. 使用CNN实现MNIST数据集分类

    1 MNIST数据集和CNN网络配置 关于MNIST数据集的说明及配置见使用TensorFlow实现MNIST数据集分类 CNN网络参数配置如下: 原始数据:输入为[28,28],输出为[1,10] ...

  5. 【framework】Activity启动流程

    1 前言 ATMS启动流程 介绍了 ActivityTaskManagerService(ATMS)的启动和初始化流程,本文将介绍 Activity 的启动流程.由于 Activity 启动流程复杂, ...

  6. pt-table-checksum对比数据测试(dsns方式)

    1.1.工作原理 pt-table-checksum会对校验的表数据进行数据块(数据块大小根据服务负载情况调整)划分,并对数据块数据进行checksun处理:存储在建立的表中.在主库中执行基于stat ...

  7. centos7创建MySQL自动备份脚本

    说明 最近需要给wordpress站点搞一个定时备份mysql数据库,所以记录一下. 操作步骤 1.创建备份脚本 这一步最重要,创建目录:/home/wpblog_backup,然后在目录下创建she ...

  8. postgresql常见开发技巧

    1.数据类型 名字 描述 bigint 有符号 8 字节整数 bigserial 自增八字节整数 bit [ (n) ] 定长位串 bit varying [ (n) ] 变长位串 boolean 逻 ...

  9. 全栈式测试平台RunnerGo核心功能模块-接口管理

    ​全栈式测试平台RunnerGo相对于市面上其他性能测试产品来说更简单,它不用其他相关配件,天然支持分布式,有单独的机器做分布式的负载均衡,自有一套智能算法算压力机的配置从而平均分配,并从场景链路的流 ...

  10. 类型判断,代码块,流程控制及循环---day05

    1.类型判断isinstance 用来做判断类型 语法: 用法一: isinstance(要判断的值,要判断的类型) 返回的是真或者假 用法二: isinstance(要判断的值,(可能的类型))如果 ...