我正在向各种MVC控制器启动多个ajax调用,以加载我页面的不同部分。然而,当它到达控制器时,似乎只有一个一次运行。我猜这是因为默认ASP.Net MVC控制器是同步的?我还测试了在2个浏览器选项卡上加载页面,第二个选项卡总是等待第一个。
为了解决这个问题,我尝试使控制器方法异步。我通过以下方式完成了这个
例如,现在所讨论的控制器方法看起来像这样......
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
};
}
然而它似乎仍然是同步的。我错过了什么或完全以错误的方式解决这个问题吗?我没有真正使用任务库,所以可能会遗漏一些大事?
答案 0 :(得分:8)
不,你的假设很可能是错误的。你的问题可能是两个问题中的一个(或两个)。
首先,大多数Web浏览器都有请求限制,一次只允许对同一服务器发出一定数量的请求。
其次,您可能遇到了Session对象的限制,导致多个请求使用session进行序列化,因为Session本身并不是多线程的。
请参阅http://tech-journals.com/jonow/2011/10/22/the-downsides-of-asp-net-session-state
简短的回答是,如果你不在你的行动方法中使用会话,只需将其添加到方法......
[SessionState(SessionStateBehavior.Disabled)]
public class AjaxTestController : Controller
{
//...As above
}
如果您只需阅读会话,请执行以下操作:
[SessionState(SessionStateBehavior.ReadOnly)]
public class AjaxTestController : Controller
{
//...As above
}
但是,由于不同的浏览器具有特定的请求限制,因此您无法对浏览器限制做些什么。这些可以通过注册表(或浏览器配置)条目(通常)进行更改,但在大多数情况下,您无法强制用户执行此操作。
答案 1 :(得分:3)
MVC 4.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();
}
}
步骤:
同步控制器是从Controller派生的类 用于实现AsyncController而不是派生的类 来自Controller的控制器,从AsyncController类派生。 从AsyncController派生的控制器启用ASP.NET 处理异步请求,它们仍然可以服务同步 行动方法。
对应同步中的同步动作方法 你需要为控制器创建两个方法 异步controller.First方法,启动异步 进程必须具有由操作和后缀组成的名称 &#34;异步&#34 ;.异步时调用的另一个方法 进程完成(回调方法)必须具有包含的名称 动作和后缀&#34;已完成&#34;。
在上面的示例示例中,Index操作已在异步控制器中转换为两个方法:IndexAsync和IndexCompleted。
当IndexCompleted方法返回ActionResult实例时,IndexAsync方法返回void。虽然操作包含两个方法,但使用与同步操作方法相同的URL(例如,Controller / Index)访问它。
请注意以下有关异步操作方法的内容:
如果操作名称为Sample,则框架将查找 SampleAsync和SampleCompleted方法。
查看页面应命名为Sample.aspx,而不是SampleAsync.aspx 或SampleCompleted.aspx。 (操作名称为Sample,而不是 SampleAsync)
控制器不能包含名为SampleAsync的异步方法 和一个名为Sample的同步方法。如果确实如此,那么 抛出AmbiguousMatchException异常,因为SampleAsync action方法和Sample action方法具有相同的请求 签名。
有关详情,请点击此处:http://www.counsellingbyabhi.com/2014/05/asynchronous-controllers-in-aspnet-mvc.html
答案 2 :(得分:0)
mvc控制器本质上是异步的,你是如何确定它是同步的?唯一的原因可能只是在userService中实现了一些锁。
您可以尝试使用jquery
对您的Web服务进行数百次ajax调用