我们在Beta HyperV环境中的MVC AsyncController上遇到了TimeoutException。在本地调试时一切正常,但是当我们部署到预生产环境时,我们会收到此错误:
[TimeoutException:操作已超时。] System.Web.Mvc.Async.WrappedAsyncResult`1.End()+129 System.Web.Mvc.Async。<> c_ DisplayClass39.b _38(IAsyncResult asyncResult)+23 System.Web.Mvc.Async。<> c_ DisplayClass33.b _2d()+125 System.Web.Mvc.Async。<> c_ DisplayClass49.b _43()+452 System.Web.Mvc.Async。<> c_ DisplayClass49.b _43()+452 System.Web.Mvc.Async。<> c_ DisplayClass49.b _43()+452 System.Web.Mvc.Async。<> c_ DisplayClass31.b _30(IAsyncResult asyncResult)+15 System.Web.Mvc.Async。<> c_ DisplayClass24.b _1a()+31 System.Web.Mvc.Async。<> c_ DisplayClass1f.b _1c(IAsyncResult asyncResult)+230 System.Web.Mvc。<> c_ DisplayClass17.b _12(IAsyncResult asyncResult)+28 System.Web.Mvc.Async。<> c_ DisplayClass4.b _3(IAsyncResult ar)+20 System.Web.Mvc.AsyncController.EndExecuteCore(IAsyncResult asyncResult)+53 System.Web.Mvc.Async。<> c_ DisplayClass4.b _3(IAsyncResult ar)+20 System.Web.Mvc。<> c_ DisplayClass8.b _3(IAsyncResult asyncResult)+42 System.Web.Mvc.Async。<> c_ DisplayClass4.b _3(IAsyncResult ar)+20 System.Web.CallHandlerExecutionStep.OnAsyncHandlerCompletion(IAsyncResult ar)+136
[OutputCache(Duration = 0, NoStore = true, VaryByParam = "")]
public void IndexAsync()
{
using (var context = Repository.CreateContext().CreateUnitOfWork())
{
user = context.Users.Single(u => u.Username == User.Identity.Name);
AsyncManager.OutstandingOperations.Increment();
ThreadPool.QueueUserWorkItem(o => {
var sync = myService.DoThingsAsync(user);
sync.AsyncWaitHandle.WaitOne();
AsyncManager.OutstandingOperations.Decrement();
});
}
}
/// IndexCompleted is never called
public ActionResult IndexCompleted(string property)
{
using (var context = Repository.CreateContext().CreateUnitOfWork())
{
var user = context.Users.Single(u => u.Username == User.Identity.Name);
var model = new MyViewModel
{
ModelProperty = user.Property
};
return View("Index", model);
}
}
出现此错误的可能原因是什么?
答案 0 :(得分:9)
这是异步操作所花费的时间超过配置的AsyncTimeout值(默认为45秒)时抛出的异常。您可以通过使用AsyncTimeout属性修饰ActionMethod来显式控制此值。例如,要将异步超时设置为整分钟:
[AsyncTimeout(60000)]
public void IndexAsync()
{
...
}
您也可以使用NoAsyncTimeout属性,但是您很容易受到从未完成的异步操作的影响,并使您的Web请求处于不稳定状态。