C# ASP.NET中带有GetRouteDataAsync和GetVirtualPath同步的异步路由库?

C# ASP.NET中带有GetRouteDataAsync和GetVirtualPath同步的异步路由库?,c#,asp.net,asp.net-mvc,async-await,url-routing,C#,Asp.net,Asp.net Mvc,Async Await,Url Routing,我有一个自定义ASP.NET路由,其中包含IO操作。目前,假设这些IO操作无法缓存(即太大) 在某种程度上,我正在寻找一个具有 public async override Task<RouteData> GetRouteDataAsync(HttpContextBase httpContext) public async override Task<VirtualPathData> GetVirtualPathAsync(RequestContext requestCon

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

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

public async override Task<RouteData> GetRouteDataAsync(HttpContextBase httpContext)
public async override Task<VirtualPathData> GetVirtualPathAsync(RequestContext requestContext, RouteValueDictionary routeValues);
公共异步覆盖任务GetRouteDataAsync(HttpContextBase httpContext) 公共异步覆盖任务GetVirtualPath同步(RequestContext RequestContext,RouteValueDictionary routeValues);
  • 类似的东西已经存在了吗?(找不到)
  • ASP.NET管道中是否有我可以自己创建的地方

我正在使用ASP.NET MVC 5.2.3.0

不幸的是,无法用
异步
方法覆盖非
异步
方法。我认为最好的选择是使用
async
non
override
方法,并从non
async
调用该方法,如:

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

public async override Task<RouteData> GetRouteDataAsync(HttpContextBase httpContext){
    //operations here
}
public override RouteData GetRouteData(HttpContextBase-httpContext){
返回GetRouteDataAsync(httpContext);
//返回等待GetRouteDataAsync(httpContext);
}
公共异步覆盖任务GetRouteDataAsync(HttpContextBase httpContext){
//这里的业务
}
注意:这可能会导致问题。如果原始代码不希望执行任何
async
代码,那么引入此模式可能会打破预期。尽可能避免


建议您不要创建AsyncRouteBase,因为ASP.NET MVC使用的路由是同步的。您必须理解,为了创建异步方法,必须有人异步使用它们,您不能通过添加异步方法神奇地使所有内容都异步

由于各种原因,路由不能是异步的,路由是缓存的,并且在执行第一个请求时只创建一次。注意,路由是缓存的,它们不会更改,并且在运行时也不能更改,因为它们是先执行的,如果路由将进行异步db调用,则每个请求都必须等待路由条件满足,这将降低整个应用程序的速度

而且您基本上不需要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中调用相应的方法。

IO需要多长时间?如果它很快(可能是在路由中),那么使用异步IO()就没有意义了。可能是多个数据库调用,每个调用大约50毫秒。好的,这对于异步IO可能没有意义。好问题,谢谢。但说真的?我想我还需要进一步研究,但是50ms听起来比你在CPU上能做的事情还要长。CPU在这段时间内不会暂停。另一条线索出现了。异步IO解决了由于每个线程有1MB堆栈内存而导致的内存使用问题。还解决了在数百个线程中设置的线程池耗尽问题,可以关闭。也许你会发现我对这些问题的讨论很有启发性。我打赌里面有一些你还不知道的相关东西。大多数人不会。嗨,阿卡什,谢谢你的回答。只需注意一点:MVC默认情况下不会缓存自定义的
RouteBase
。我怎么知道?我在(相当)复杂的路由过程中进行数据库调用:)以了解我为什么要使其异步:这与我为什么要使所有操作都异步相同——这样它们就不会阻塞不必要的线程。无论如何,请求都被暂停了(几毫秒)-而不是同时为另一个请求提供服务。带有
httptasksynchHandler
的部分听起来很有趣,这可能是答案-我必须弄清楚如何以及是否可以在MVC中实现它,同时保留所有现有的行为。