Web API消息处理程序可以依赖其他消息处理程序的结果吗?

时间:2014-09-16 13:35:46

标签: .net controller asp.net-web-api handlers

考虑消息处理程序使用SendAsync从执行中返回,例如:

var response = await base.SendAsync(request, cancellationToken);

这是否意味着每个消息处理程序都无法保证先前的消息处理程序能够完成它之前的工作?

例如,如果以下处理程序列表中的B最慢完成,那么执行是否会像这样开始:

A,B,C

但是这样回来:

A,C,B

如果是这样,这是否意味着在所有处理程序完成之前控制器不会被执行,或者控制器是否可以在正确填充请求对象之前开始执行?

1 个答案:

答案 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”部分。