提问人:Morfhine 提问时间:11/14/2023 最后编辑:marc_sMorfhine 更新时间:11/15/2023 访问量:53
在 Core 5 MVC 应用程序中 ASP.NET ControllerActionInvoker.InvokeActionAsync 方法似乎在同一线程中同时调用两次?
In ASP.NET Core 5 MVC app, ControllerActionInvoker.InvokeActionAsync method seems to be called twice in the same thread simultaneously?
问:
我使用 CLR 探查器以原始 APM 的方式记录框架方法。在使用它时,请求流通常流经我动态插入到应用程序中的中间件,然后流向请求处理程序。
在本例中,(ASP.NET Core 5 MVC),这里的请求线程将是相同的,其中函数返回一个对象,并且任务在线程池中的单独线程上继续。但是,在第一个方法返回 Task 对象之前,如何在同一线程中第二次触发呢?仅当负载较高时才会发生这种情况,否则请求流是可预测的。ControllerActionInvoker
InvokeActionAsync()
Task
InvokeActionAsync()
日志如下:
13-11-2023 21:00:03 [4:(DEBUG)<t:23>] - [TName: ] MiddleWarePipeline.Invoke is called
13-11-2023 21:00:03 [4:(DEBUG)<t:23>] - [TName: ] Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeActionMethodAsync is called.
13-11-2023 21:00:03 [4:(DEBUG)<t:23>] - [TName: ] Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeActionMethodAsync is called.
13-11-2023 21:00:03 [4:(DEBUG)<t:23>] - [TName: ] ----- some other -----
13-11-2023 21:00:03 [4:(DEBUG)<t:23>] - [TName: ] ------functions ------
13-11-2023 21:00:03 [4:(DEBUG)<t:23>] - [TName: ] ------are getting-----
13-11-2023 21:00:03 [4:(DEBUG)<t:23>] - [TName: ] ----logged that ------
13-11-2023 21:00:03 [4:(DEBUG)<t:23>] - [TName: ] -------happen inside ----
13-11-2023 21:00:03 [4:(DEBUG)<t:23>] - [TName: ] ----that particular -----
13-11-2023 21:00:03 [4:(DEBUG)<t:23>] - [TName: ] ------action method-----
13-11-2023 21:00:03 [4:(DEBUG)<t:23>] - [TName: ] Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeActionMethodAsync has returned task obj.
13-11-2023 21:00:03 [4:(DEBUG)<t:23>] - [TName: ] Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeActionMethodAsync has returned task obj.
13-11-2023 21:00:03 [4:(DEBUG)<t:23>] - [TName: ] MiddleWarePipeline.Invoke has returned obj.
这是预期的行为吗?这是触发两次的同一请求,还是两个请求?如果是两个,它们如何区分同一线程中的两个请求?InvokeActionAsync()
答:
请求线程将与 InvokeActionAsync() 函数返回一个 Task 对象,并且该任务在单独的 线程池中的线程。但是 InvokeActionAsync() 会如何 在第一个方法之前,在同一线程中第二次触发 甚至返回了 Task 对象,这是预期的行为吗?这是 触发 InvokeActionAsync() 两次的相同请求,还是两次 请求?
首先,中间件执行两次并不是缺点。通常,这是执行中间件两次时的预期行为,因为当执行 HTTP 请求时,通常会命中两个端点。因此,中间件执行两次。
如果调试应用程序,则会发现将执行第一个调用 InvokeActionAsync 以加载应用程序本身,基本路径应为域/本地主机或 ./
第二次,您的应用程序具有其资源文件。例如,css、js 或应用程序根文件夹中需要额外执行的任何其他内部文件。
请查看以下网络跟踪日志:
注意:但是,有时,如果您没有通常在程序启动时调用的其他资源,则不会为同一线程中的同一请求多次调用此方法。例如,静态文件。
如果是两个,他们如何区分 同一个线程?
好吧,对于 ASP.NET Core,为了区分同一线程中的多个请求,它使用与每个请求关联的 HttpContext 对象。HttpContext 包含有关当前请求的信息,包括标头、参数和其他相关详细信息。此上下文对于每个传入请求都是唯一的,它用于区分不同的请求,即使它们正在同一个线程上处理。
如果需要更精确地了解在特定方案中调用两次 InvokeActionAsync 的原因,可以分析调用堆栈,在请求处理期间记录其他信息。
此外,在每次调用期间检查 HttpContext 有助于识别两次调用之间的任何差异
注意:如果您想知道如何查看 httpContext 详细信息和后台线程,请参阅此官方文档了解更多信息。
评论