ASP.NET Core中单个与多个app.UseWhen的差异及性能疑问
ASP.NET Core中UseWhen两种注册方式的差异分析
功能一致性
两种写法功能上完全等价:都会针对路由控制器不是"SomeValue"的请求,依次执行SessionMiddleware和SomeOtherMiddleware,中间件的执行顺序也保持一致(先SessionMiddleware,后SomeOtherMiddleware)——因为中间件的执行顺序由注册顺序决定,和是否在同一个UseWhen分支内无关。
运行时开销差异
分开注册(写法二)会产生轻微的额外开销:
- 写法一中,每个符合条件的请求只会执行一次路由控制器的判断逻辑(
context.GetRouteValue("controller") is not "SomeValue"),然后在同一个分支管道中依次执行两个中间件。 - 写法二中,每个符合条件的请求会执行两次相同的路由判断逻辑,因为每个
UseWhen都会独立执行自己的条件检查。虽然单条判断的性能损耗极小,但在高频请求场景下会有累积的性能差异。
编译器优化情况
编译器不会将两种写法优化为相同实现。这是因为UseWhen是应用启动时构建中间件管道的运行时逻辑,编译器无法预知运行时的请求路由情况,也不会自动合并独立的UseWhen分支。写法一对应一个分支管道,写法二对应两个独立的分支管道,二者的运行时处理逻辑本质不同。
推荐方案
优先选择写法一:
- 减少重复的条件判断逻辑,代码更简洁易维护;
- 降低不必要的运行时性能损耗;
- 后续添加同分支的中间件时,无需重复编写判断条件,扩展性更好。
示例代码回顾
初始禁用会话的代码:
app.UseWhen( context => context.GetRouteValue("controller") is not "SomeValue", app => app.UseMiddleware<SessionMiddleware>());
写法一(单分支注册多个中间件):
app.UseWhen( context => context.GetRouteValue("controller") is not "SomeValue", app => { app.UseMiddleware<SessionMiddleware>(); app.UseMiddleware<SomeOtherMiddleware>(); });
写法二(多分支分别注册中间件):
app.UseWhen( context => context.GetRouteValue("controller") is not "SomeValue", app => app.UseMiddleware<SessionMiddleware>()); app.UseWhen( context => context.GetRouteValue("controller") is not "SomeValue", app => app.UseMiddleware<SomeOtherMiddleware>());
内容的提问来源于stack exchange,提问作者Slepoyi
相关产品推荐
相关产品推荐

