ASP.NET 6 中间件系列 - 执行顺序

80b73b8994a1510e000abad6ac297281.png

这篇文章是 ASP.NET 6 中间件系列文章的第 3 部分,你还可以阅读第1部分和第2部分。

我们通过中间件创建的管道是有执行顺序的,执行顺序与中间件的添加顺序是相同的,接下来我们讨论一下为什么要有执行顺序,以及它的重要性。

示例项目

在 GitHub 上可以获得这篇文章涉及到的代码:

https://github.com/zilor-net/ASPNET6Middleware/tree/Part3

执行顺序

在本系列的第1部分中,中间件构成了一个管道,该管道中的中间件按照一定的顺序执行,如下图所示:

f5421de9e3f981b4e2b1733e8fa8326f.png

请求按顺序经过各个中间件,而响应则按相反的顺序返回。

在前面的文章中,我们已经定义了两个中间件类:

  • LoggingMiddleware用于记录请求/响应日志;

  • SimpleResponseMiddleware用于中断管道,返回响应。

在这篇文章中,我们仍然以LoggingMiddleware为例:

app.UseLoggingMiddleware();

添加延迟

我们创建一个新的中间件类,叫做IntentionalDelayMiddleware,它看起来像这样:

namespace  MiddlewareNET6Demo.Middleware
{public  class  IntentionalDelayMiddleware{private  readonly RequestDelegate _next;public IntentionalDelayMiddleware(RequestDelegate next){_next = next;}public async Task InvokeAsync(HttpContext context){await Task.Delay(100);await _next(context);await Task.Delay(100);}}
}

这个中间件在处理传入请求和处理传出响应时都会等待 100ms,总等待时间为 200ms。

当然,实际场景下,我们并不会这么做。

在这里,IntentionalDelayMiddleware只是代表了某种未定义的中间件,它需要一个可预测的时间来执行。

我们需要向管道中添加一个IntentionalDelayMiddleware的实例。问题在于,我们是在LoggingMiddleware之前还是之后添加它?

其实在这种情况下,这个问题可能并不重要,因为这两个中间件不会进行交互,也不处理相同的事情。

在这个示例中,让我们在LoggingMiddleware之后添加IntentionalDelayMiddleware

app.UseLoggingMiddleware();
app.UseIntentionalDelayMiddleware();

如果现在运行应用程序,我们可能不会发现明显的差异,因为 200 毫秒相当快。

添加执行时间中间件

为了监视每个请求的所消耗的时间,我们往往需要记录每个请求到我们系统的执行时间。

这个需求对于中间件来说是非常简单的,我们可以使用 .NET 提供的Stopwatch类和第2篇文章中创建的LoggingService来实现。

下面是名为TimeLoggingMiddleware的中间件类:

using MiddlewareNET6Demo.Logging;
using System.Diagnostics;namespace  MiddlewareNET6Demo.Middleware
{public  class  TimeLoggingMiddleware{private  readonly RequestDelegate _next;private  readonly ILoggingService _logger;public TimeLoggingMiddleware(RequestDelegate next, ILoggingService logger){_next = next;_logger = logger;}public async Task InvokeAsync(HttpContext context){Stopwatch watch = new Stopwatch();watch.Start();await _next(context);watch.Stop();_logger.Log(LogLevel.Information, "Time to execute: " + watch.ElapsedMilliseconds + " milliseconds.");}}
}

我们需要将其添加到管道中。但是,这里仍然有个问题:我们应该添加到哪个位置?

如果我们将TimeLoggingMiddleware添加到IntentionalDelayMiddleware之前,那么后者所引起的延迟将包含在前者所度量的范围中。

如果我们将TimeLoggingMiddleware添加到IntentionalDelayMiddleware之后,那么后者所引起的延迟将不会包含在前者所度量的范围中。

让我们来看看管道:

app.UseHttpsRedirection();
app.UseStaticFiles();// 如果该中间件发生任何延迟,那么该延迟不会包含在时间日志中。
app.UseLoggingMiddleware();// 时间记录中间件
app.UseTimeLoggingMiddleware();// 延迟中间件。
// 此时,延迟被包含在时间日志中。
app.UseIntentionalDelayMiddleware();app.UseRouting();app.UseAuthorization();app.MapRazorPages();app.Run();

在这个 Program.cs 文件中,哪个位置更适合放置TimeLoggingMiddleware?其答案取决于几个问题:

  • 时间日志需要包括诸如无效授权之类的执行时间吗?如果是,那么必须在调用app.UseAuthorization()之前,放置TimeLoggingMiddleware

  • 路由调用需要的时间非常少,但可以测量。我们要把它包括进去吗?如果是,就必须在调用app.UseRouting()之前,放置TimeLoggingMiddleware

像大多数现实世界的问题一样,这个问题没有明确的答案。

如果没有明确的指示,那么这最终需要由开发人员根据系统的具体情况来做出决定。

需要注意的是:

app.UseIntentionalDelayMiddleware();
app.UseTimeLoggingMiddleware();

这两个是完全不同的:

app.UseTimeLoggingMiddleware();
app.UseIntentionalDelayMiddleware();

这就是为什么中间件在管道中顺序很重要的一个例子。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/288935.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

OSChina 周四乱弹 ——程序员怎么撩外国妹子攻略

2019独角兽企业重金招聘Python工程师标准>>> Osc乱弹歌单(2017)请戳(这里) 【今日歌曲】 冬天之雪 :听歌听到苏菲玛索和刘欢演唱《玫瑰人生》。有网友评论:法语专业的刘欢老师等的就是这一刻。…

【C语言简单说】七:自定义函数(3)

前一节说了返回值的内容,那么这一节就说一下参数的内容 手打码了几章内容了。。。。困。^( ̄) ̄)《( ̄) ̄)^困.困.困. 相比看过前一节的知道我说自定义函数如果你要做一个运…

WireShare抓包在ssl协议里面提示(Level: Fatal, Description: Protocol Version)

1 问题 在后台访问部分链接的时候抓包,客户端发了client hello包,但是没有收到Server hello包, 提示:Alert(Level: Fatal, Description: Handshake Failure ) 包文如下 2 解决办法 是因为客户端的ssl协议版本和链接地址环境ss…

对于 APM 用户的一次真实调查分析(下)

一.前言 对 APM 用户的一次真实调查分析(上)中,我们主要聊到了现阶段国外 APM 行业对各个企业的渗透率、大部分使用 APM 工具的企业规模以及 APM 工具在用户心中的地位等问题,有兴趣的朋友可以点击链接观看。 我们本次继续顺着这个…

linux cpu核数查看_Linux日常必备的 8 个小技能

身为一个码农,日常工作中与我们打交道次数较多的操作系统除了Windows和Mac OS 之外,还有一个就是 Linux。今天偶尔有空翻越了之前码代码时期汇总的一些小技巧发现挺实用的,故分享给大家,希望能对大伙有一定的帮助。1. 如何查看系统…

NotificationManagerService使用详解与原理分析(一)

概况 Android在4.3的版本中(即API 18)加入了NotificationListenerService,根据SDK的描述(AndroidDeveloper)可以知道,当系统收到新的通知或者通知被删除时,会触发NotificationListenerService的回调方法。同时在Android 4.4 中新增了Notifica…

【C语言简单说】八:分支结构之if(1)

今天貌似更了很多章了,现在感觉累觉不爱。。。 ┐(—__—)┌ 你说我有啥米办法咧~(要不叫别人替我更一下?) 继续更。。。 这一节我们来说一下if语句;这个东西可是很常用的呀;在此之前我们来举个例子&…

ASP.NET 6 中间件系列 - 自定义中间件类

这篇文章是 ASP.NET 6 中间件系列文章的第2部分,点击这里可以阅读第1部分。在上一篇文章中,我们讨论了什么是中间件,它的作用是什么,以及在 ASP.NET 6 应用管道中添加中间件的简单方法。在这篇文章中,我们将在这些基础…

如何在IE浏览器里面定位到关键字的位置(页面代码)和这个关键字位置模块的请求

1 问题 比如用IE浏览器,打开一个页面,如何定位到关键字的具体位置,以及这个位置请求是什么?可能这个请求不是主页面的请求,因为我们知道页面html里面可以嵌套很多Frame(框架),把页面分割成很多块,然而每个Frame(框架)里面可以再嵌套一个url,有时候我们需要找到这个请求…

Java并发编程-原子性变量

image.png1. 原子性布尔 AtomicBoolean AtomicBoolean 类为我们提供了一个可以用原子方式进行读和写的布尔值,它还拥有一些先进的原子性操作,比如 compareAndSet()。AtomicBoolean 类位于 java.util.concurrent.atomic 包,完整类名是为 java.…

【C语言简单说】八:分支结构之if...else...(2)

上一节我们说了if的基本用法,这一小节我们来说明if…else…的用法 首先惯例举例子: 你今天早上饿了,打算去吃包子,可是没有包子了,你打算去吃米粉。 你昨天早上下雨了,带伞出门,结果没找到&a…

Java集合之LinkedList

上一篇写的是ArrayList,这一篇写一下LinkedList. 开宗明义,因为Vector已经被废弃了,所以list家族只剩下ArrayList和LinkedList两兄弟了,这里直接对比一下二位: ArrayList基于动态数组的实现,它长于随机访问…

由于开发者通过接口修改了菜单配置_Android SDK开发艺术探索(四)个性化配置...

一、前言本篇是Android SDK开发艺术探索系列的第四篇文章。介绍了通过流式API设计思想优雅地实现SDK的自定义选项配置需求。目录概览:一、前言 二、SDK自定义配置2.1、什么是自定义配置2.2、设计一个配置方法 三、结语系列文章:Android SDK开发艺术探索&…

C#中切片语法糖的使用

例子首先我们看这样一个例子,有这样一个数组string [] lst new string[] { "1", "2", "3", "4", "5", "6", "7" };我们怎么获取它的最后一个值, 传统方法是这样写的&#xff0c…

JavaScript 语言基础知识点总结(思维导图)

1.JavaScript数组 2.JavaScript 函数基础 3.Javascript 运算符 4.JavaScript 流程控制 5.JavaScript 正则表达式 6.JavaScript 变量 7.JavaScript 字符串函数 8.DOM 基本操作 制作工具:Mindjet MindManager 文章摘自:http://m.oschina.net/blog/175426转…

linux之一些比较新但是常用的命令(expr ag tree cloc stat tmux axel)

1 expr命令 介绍:这个命令用来匹配正则表达式,这个命令linux系统自带,不信你自己试下 使用:expr 正则表达式 输出结果 expr http:\/\/www\.baidu\.com http//www.baidu.com 用了这个命令,我们就不需要在网上去搞在线正则表达式匹配 2 tree命令 这个命令需要安装 sudo…

基于tiny4412的Linux内核移植 -- MMA7660驱动移植(九)

作者信息 作者: 彭东林 邮箱:pengdonglin137163.com QQ:405728433 平台简介 开发板:tiny4412ADK S700 4GB Flash 要移植的内核版本:Linux-4.4.0 (支持device tree) u-boot版本:友善之臂自带的…

【C语言简单说】八:分支结构之if...else if()...else...(3)

既然前面几种情况大家都了解了话&#xff0c;这一节的话我就不举例子了。。。 直接上代码&#xff1a; #include<stdio.h> #include<stdlib.h> int main() {int a1;if(a1){printf("a的值等于1\n");}else if(a2){printf("a的值等于2\n"); …

最通俗易懂的依赖注入与控制反转

这是一个关于 ASP.NET 6 依赖注入的系列文章。在这个系列中&#xff0c;我们将了解到什么是依赖注入、控制反转&#xff0c;它能够做什么&#xff0c;以及我们为什么要使用它。之后&#xff0c;我们会进一步了解 ASP.NET 6 依赖注入的生命周期、服务容器等重要概念。最后&#…

word公式编辑器_论文查重算公式吗 公式怎样避免查重?

论文查重算公式吗 公式怎样避免查重?每一个毕业生想要毕业都要经过论文查重这一关&#xff0c;仅有通过了论文查重&#xff0c;才可以进入答辩。在论文检测的情况下&#xff0c;不少同学论文中一定会应用大批量的计算公式&#xff0c;且计算公式全部都是固定不动的&#xff0c…