考虑消息处理程序使用SendAsync从执行中返回,例如:
var response = await base.SendAsync(request, cancellationToken);
这是否意味着每个消息处理程序都无法保证先前的消息处理程序能够完成它之前的工作?
例如,如果以下处理程序列表中的B最慢完成,那么执行是否会像这样开始:
A,B,C
但是这样回来:
A,C,B
如果是这样,这是否意味着在所有处理程序完成之前控制器不会被执行,或者控制器是否可以在正确填充请求对象之前开始执行?
答案 0 :(得分:0)
在委派消息处理程序的情况下,每个通过调用base.SendAsync
启动下一个,然后(异步)等待使用await
完成它。因此,他们可以处理前后条件。
普通代码的工作方式正如您所期望的那样:
// At this point, no later handlers (or the controller) have executed.
// All earlier handlers have run up until the point they call base.SendAsync.
var response = await base.SendAsync(request, cancellationToken);
// At this point, all later handlers (and the controller) have executed and completed.
// All earlier handlers are (asynchronously) waiting for you to complete.
C
无法在B
之前完成,因为B
正在SendAsync
等待C
,因此B
不会完成直到C
完成。
请记住,消息处理程序是双向。它们分为“前”部分(base.SendAsync
调用之前)和“后”部分(从await
返回的任务的base.SendAsync
之后)。因此,当调用处理程序的SendAsync
时,您知道早期过滤器的所有“前”部分已经运行,但没有一个“post”部分。对于控制器也是如此:所有过滤器的所有“预”部分都已运行,但没有“后”部分。
现在,如果你做了一些不好的事情,比如 not 等待从base.SendAsync
返回的任务,那么你就不会得到上面的好处,事情变得复杂了。但绝大多数情况下,您的处理程序代码会执行await base.SendAsync
,并且会干净地拆分为“pre”和“post”部分。