ASP.NET中的异步RouteBase与GetRouteDataAsync和GetVirtualPathAsync?

时间:2015-07-18 09:49:27

标签: c# asp.net asp.net-mvc async-await url-routing

我有一个自定义ASP.NET路由,其中​​包含IO操作。现在,假设这些IO操作无法缓存(即太大)。

在某种程度上,我正在寻找一个带有

AsyncRouteBase课程
public async override Task<RouteData> GetRouteDataAsync(HttpContextBase httpContext)
public async override Task<VirtualPathData> GetVirtualPathAsync(RequestContext requestContext, RouteValueDictionary routeValues);
  • 类似的东西已经存在吗? (找不到)
  • ASP.NET管道中是否有可以自行创建的地方?

我正在使用ASP.NET MVC 5.2.3.0

2 个答案:

答案 0 :(得分:1)

您无法创建AsyncRouteBase,因为ASP.NET MVC使用的路由是同步的。你必须明白,为了你创建异步方法,有人必须异步使用它们,你不能通过添加异步方法神奇地使所有异步。

由于各种原因,路由不能异步,路由被缓存,并且只在执行第一个请求时创建一次。请注意,路由被缓存,它们不会更改,并且它们无法在运行时更改,因为它们首先执行,如果路由将进行异步数据库调用,则每个请求都必须等待路由条件实现,这将减慢整个申请。

而且您大多不需要AsyncRouteBase,而是可以创建异步路由处理程序。

public class AsyncRouteHandler : IRouteHandler
{
    IHttpHandler IRouteHandler.GetHttpHandler(RequestContext requestContext)
    {
        return new AsyncHttpHandler();
    }
}

public class AsyncHttpHandler : HttpTaskAsyncHandler{
    public override async Task ProcessRequestAsync(HttpContext context)
    {        
    }
}

但是,在其中使用MVC管道需要大量工作,但您可以轻松忽略它并从此处为您的响应提供服务。您可以在其中使用控制器工厂并创建您的方法来执行您需要的工作。

其他替代方法是轻松使用MEF或其他形式的DI来管理更大的代码库并调用AsyncHttpHandler中的相应方法。

答案 1 :(得分:0)

很遗憾,无法使用async覆盖非async方法。我认为您最好的选择是使用asyncoverride方法并从非async方式调用该方法,如:

public override RouteData GetRouteData(HttpContextBase httpContext) {
    return GetRouteDataAsync(httpContext);
    //return await GetRouteDataAsync(httpContext);
}

public async override Task<RouteData> GetRouteDataAsync(HttpContextBase httpContext){
    //operations here
}

注意:这可能会导致问题。如果原始代码没有期望任何async代码执行,那么引入这种模式可能会打破期望。如果可能,请避免使用它。

作为建议,请参阅Simplify Asynchronous Programming with Tasks