ASP.NET MVC,ajax请求不是异步处理的

时间:2014-08-04 09:32:00

标签: c# ajax asp.net-mvc asp.net-mvc-4 request

我正在进行一项大型应用项目,我们已经研究了一段时间。我90%肯定这是一个实际上没有问题的新问题。

当我调用两个ajax请求时,第二个请求在处理前等待第一个完成。当我检查网络流量时,我可以看到客户端(浏览器)将两个请求都发送到服务器,但它似乎是一次只提供一个请求的服务器。

我无法弄清楚这是什么。我找到了答案,说它可能是属性enableSessionState,它使MVC同步服务请求,所以我调查了一下,没有帮助。

我开始了一个新的MVC 4项目,并制作了一个完全符合我想要的示例代码。我们的主要项目必须搞砸了。

我会发布一些代码。关键是我想要开始一个程序或需要一段时间才能完成的程序。然后从日志中读取以向用户呈现进度信息。但是现在程序开始并且当它结束时,用户获得在结束时同时收集的所有信息。 但是当它工作时,就像在新项目中一样,用户在慢速程序仍在执行时逐个获取信息。

有没有人有一些可能对我有帮助的想法?把我指向正确的方向哪里看更多?

查看:

@{
    ViewBag.Title = "Index";
}

<style>
    .calculation {
        overflow-y:scroll;
        width:400px;
        height:600px;
        background-color:#eee;
        border:solid 1px #000;
        padding:10px;
    }
</style>
<script src="~/Scripts/jquery-1.8.2.js"></script>
<h2>Index</h2>

<div class="calculation"></div>

<script>
    $(function () {
        $.ajax({
            type: 'POST',
            url: 'Calculation/DoSlowCalculation',
            contentType: 'application/json; charset=utf-8'
        });

        function readLog() {
            $.ajax({
                type: 'POST',
                url: 'Calculation/ReadCalculationLog',
                contentType: 'application/json; charset=utf-8',
                success: function (log) {
                    var completed = false,
                        div = $('.calculation');
                    for (var c1 = 0, l = log.length; c1 < l; c1++) {
                        div.prepend('<div>' + log[c1].LogText + '</div>');
                        if (log[c1].Complete) { completed = true; }
                    }
                    if (completed) {
                        alert('Calculation completed');
                    }
                    else {
                        setTimeout(function () {
                            readLog();
                        }, 1000);
                    }
                }
            });
        }

        readLog();
    });
</script>

控制器:

public class CalculationController : Controller
    {
        public ActionResult Index()
        {
            return View("Index");
        }

        public void DoSlowCalculation()
        {
            using (var conn = new SqlConnection("Server=.;Database=SlowCalculationDB;Trusted_Connection=True;"))
            {
                using (var cmd = new SqlCommand(@"
                    INSERT INTO Log
                    VALUES ('Starting calculation', GETDATE(), 0, 0);

                    WAITFOR DELAY '00:00:04'

                    INSERT INTO Log
                    VALUES ('Some more calculation...1', GETDATE(), 0, 0);

                    WAITFOR DELAY '00:00:04'

                    INSERT INTO Log
                    VALUES ('Some more calculation...2', GETDATE(), 0, 0);

                    WAITFOR DELAY '00:00:04'

                    INSERT INTO Log
                    VALUES ('Some more calculation...3', GETDATE(), 0, 0);

                    WAITFOR DELAY '00:00:04'

                    INSERT INTO Log
                    VALUES ('Some more calculation...4', GETDATE(), 0, 0);

                    WAITFOR DELAY '00:00:04'

                    INSERT INTO Log
                    VALUES ('Ends calculation', GETDATE(), 0, 1);
                ", conn))
                {
                    conn.Open();
                    cmd.ExecuteNonQuery();
                }
            }
        }

        public ActionResult ReadCalculationLog()
        {
            using (var conn = new SqlConnection("Server=.;Database=SlowCalculationDB;Trusted_Connection=True;"))
            {
                using (var cmd = new SqlCommand(@"
                    SELECT LogText, LogTime, Complete FROM Log WHERE [Read] = 0;
                    UPDATE Log SET [Read] = 1;
                ", conn))
                {
                    conn.Open();
                    var dt = new DataTable();
                    var sqlAdapter = new SqlDataAdapter(cmd);
                    sqlAdapter.Fill(dt);

                    var logs = from l in dt.AsEnumerable()
                               select new
                               {
                                   LogText = l.Field<string>("LogText"),
                                   LogTime = l.Field<DateTime>("LogTime").ToString("HH:mm:ss"),
                                   Complete = l.Field<bool>("Complete")
                               };

                    return Json(logs.ToList());
                }
            }
        }
    }

1 个答案:

答案 0 :(得分:2)

MVC将同步处理同一用户发出的请求,因此当您启用会话时,您也启用了此功能。

要允许异步处理操作,必须使用[SessionState(System.Web.SessionState.SessionStateBehavior.ReadOnly)]注释控制器,如下所示:

[SessionState(System.Web.SessionState.SessionStateBehavior.ReadOnly)]
public class ParallelController : Controller
{
...
}

这不适用于操作级别,因此您可能需要为相关操作使用单独的控制器。