MVC 4.5异步Ajax调用无法工作

5

我有一个在控制器上运行缓慢的操作,我已将其转换为新的异步方法。现在它运行得更快了,但任何jQuery Ajax调用它都会返回以下字符串:

System.Threading.Tasks.Task`1[System.Web.Mvc.ActionResult]

无需等待异步操作完成。

我在这里做错了什么?我遵循了我能找到的每一个示例,这不是实现起来非常简单的事情。

基本上按照这个视频中概述的方式进行:

http://channel9.msdn.com/Events/TechDays/Techdays-2012-the-Netherlands/2287

还有这个链接:

http://www.asp.net/mvc/tutorials/mvc-4/using-asynchronous-methods-in-aspnet-mvc-4#CreatingAsynchGizmos

我知道异步操作不会改变HTTP,但我期望长时间运行的Ajax调用在后台工作,然后在完成后向用户返回结果。这将释放服务器以处理其他ajax调用,而不是阻止它们。

更新:

以下是JavaScript代码:

function doWork(options){
    return $.ajax("/getData", {
                    contentType: 'text/json',
                    async: true,
                    success: $.proxy(options.callback, options.scope),
                    error: function (jqXHR, textStatus, error) {
                        options.callback.apply(options.scope, [error, textStatus, jqXHR]);
                    }
                });
}

以下是我的C#控制器操作:

[HttpGet]
[AsyncTimeout(60000)]
public async Task<ActionResult> GetData()
        {
            RestResponse<Data> response = new RestResponse<Data>();

            try
            {
                Data result = null;

                await Task.Factory.StartNew(() =>
                {
                    result = ServerImpl.RetrieveData();
                });

                response.Value = result;
                response.HttpStatusCode = 200;
            }
            catch (Exception ex)
            {
                response.HttpStatusCode = 500;
                response.Value = null;
            }

            return Json(response, JsonRequestBehavior.AllowGet);
        }

你在控制器操作中使用ASP.NET Session了吗? - Darin Dimitrov
2
那就是你的问题。ASP.NET会话不允许您从同一会话执行并行请求。由于ASP.NET会话不是线程安全的,因此ASP.NET将简单地阻止来自同一会话的并发访问服务器并使它们等待和顺序执行。ASP.NET会话引入状态以及您应用程序中的许多其他问题,这是一个设计异味。如果要拥有可扩展且无状态的应用程序,首先应该做的是摆脱它。 - Darin Dimitrov
@Darin 谢谢你的帮助。我们将尝试围绕此更改我们的架构。我很惊讶发现这很难找到相关信息。如果您提交答案,我将非常乐意将其标记为已接受。 - Matt
我已将我的评论发布为答案。 - Darin Dimitrov
2个回答

11

问题在于您的服务器端操作使用了不支持多线程的ASP.NET Session。因此,ASP.NET会将来自同一Session的并行请求排队,并按顺序执行它们。依赖Session的RESTful API是非常糟糕的设计,我认为应该重新架构,以便不依赖状态。


我认为我有同样的问题。但是我不知道如何禁用会话。我已经在web.config中禁用了,但任务仍未解决。 - Davide Icardi

3

我认为我遇到了相同的问题,即使用Session会阻止我的请求并发运行。由于我已经不修改会话,因此在我的控制器上使用此属性装饰允许请求现在并发运行。
[SessionState(SessionStateBehavior.ReadOnly)]


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接