簡體   English   中英

ASP.NET MVC,ajax請求未異步處理

[英]ASP.NET MVC, ajax requests are not being processed asynchronously

我有一個很大的應用程序項目,我們已經進行了一段時間。 我有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());
                }
            }
        }
    }

MVC將同步處理同一用戶的請求,因此,當您啟用會話時,也會同時啟用它。

要允許異步處理動作,您必須使用[SessionState(System.Web.SessionState.SessionStateBehavior.ReadOnly)]注釋控制器,如下所示:

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

這在操作級別將不起作用,因此您可能需要對所討論的操作使用單獨的控制器。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM