Asp.net mvc 4 如何使ASP.NET MVC控制器方法异步
我正在对各种MVC控制器启动多个ajax调用,以加载页面的不同部分。然而,当这到达控制器时,似乎一次只运行一个。我猜这是因为默认情况下ASP.NETMVC控制器是同步的?我还测试了在两个浏览器选项卡上加载页面,第二个选项卡总是等待第一个 为了解决这个问题,我尝试使讨论中的控制器方法异步。我做了以下几点来做到这一点Asp.net mvc 4 如何使ASP.NET MVC控制器方法异步,asp.net-mvc-4,task-parallel-library,Asp.net Mvc 4,Task Parallel Library,我正在对各种MVC控制器启动多个ajax调用,以加载页面的不同部分。然而,当这到达控制器时,似乎一次只运行一个。我猜这是因为默认情况下ASP.NETMVC控制器是同步的?我还测试了在两个浏览器选项卡上加载页面,第二个选项卡总是等待第一个 为了解决这个问题,我尝试使讨论中的控制器方法异步。我做了以下几点来做到这一点 将异步附加到控制器方法名称 使控制器方法返回异步任务 使用Task.Factory.StartNew方法在单独的线程中完成方法中的工作主体 例如,现在讨论的控制器方法如下所示
public async Task<JsonResult> GetUser(int userId)
{
var result = await Task.Factory.StartNew(() => Task.Run(() =>
{
return userService.GetUser(userId);
})).Result;
return new JsonResult()
{
Data = result,
JsonRequestBehavior = JsonRequestBehavior.AllowGet
};
}
公共异步任务GetUser(int userId)
{
var result=wait Task.Factory.StartNew(()=>Task.Run(()=>
{
返回userService.GetUser(userId);
})).结果;
返回新的JsonResult()
{
数据=结果,
JsonRequestBehavior=JsonRequestBehavior.AllowGet
};
}
然而,它似乎仍然是同步的。我是错过了什么,还是完全走错了方向?我没有太多地使用任务库,因此可能遗漏了一些重要的内容?不,您的假设很可能是错误的。您的问题可能是两个问题中的一个(或两个) 首先,大多数web浏览器都有请求限制,一次只允许向同一服务器发出一定数量的请求 其次,您可能遇到了会话对象的限制,导致使用会话的多个请求被序列化,因为会话本身不是多线程的 看 简单的回答是,如果在操作方法中不使用会话,只需将其添加到方法中即可
[SessionState(SessionStateBehavior.Disabled)]
public class AjaxTestController : Controller
{
//...As above
}
如果您只需要阅读会话,请执行以下操作:
[SessionState(SessionStateBehavior.ReadOnly)]
public class AjaxTestController : Controller
{
//...As above
}
但是,对于浏览器的限制,您无能为力,因为不同的浏览器有特定的请求限制。这些可以通过注册表(或浏览器配置)项(通常)进行更改,但在大多数情况下,您不能强制用户这样做。mvc控制器本质上是异步的,您如何确定它是同步的?唯一的原因可能是在userService中实现了一些锁
您可以尝试使用jquery对web服务进行数百次ajax调用,MVC4.0中引入的一个重要特性是异步控制器,它支持编写异步操作方法。异步控制器允许在不使工作线程空闲的情况下执行操作 调用异步操作时,将执行以下步骤: Web服务器从线程池(工作线程)获取一个线程,并安排它处理传入的请求。此工作线程启动异步操作。工作线程返回到线程池以服务另一个Web请求。异步操作完成后,将通知ASP.NET。Web服务器从线程池(可能是启动异步操作的线程的不同线程)获取工作线程,以处理请求的其余部分,包括呈现响应 将同步操作方法转换为异步操作方法 下面是同步操作方法及其异步等效版本的示例 同步控制器:
public class TestController : Controller
{
public ActionResult Index()
{
return View();
}
}
上述操作的异步变体:
public class TestController : AsyncController
{
public void IndexAsync()
{
return View();
}
public ActionResult IndexCompleted()
{
return View();
}
}
步骤:
- 同步控制器是从控制器派生的类 类来实现AsyncController,而不是派生 控制器,从AsyncController类派生它。 从AsyncController派生的控制器使ASP.NET能够 处理异步请求,它们仍然可以为同步请求提供服务 行动方法
- 对应于同步中的同步动作方法 您需要为中的操作创建两个方法 异步控制器。启动异步控制器的第一个方法 进程的名称必须由操作和后缀组成 “异步”。异步调用时调用的另一个方法 进程完成(回调方法)的名称必须包含 操作和后缀“已完成”
有关更多详细信息,请单击此处:将会话设置为禁用或只读会解决此问题。在我找到的异步控制器示例中,没有看到任何提到这一点的内容。谢谢lot@Gavin-这是因为问题与异步无关。异步用于获得更好的资源可伸缩性。这个问题是特定于会话的。@Gavin-顺便说一句,这是XY问题的一个经典示例。-您有问题,您的请求正在序列化