簡體   English   中英

異步控制器通過 jQuery 阻塞 ASP.NET MVC 中的請求

[英]Asynchronous Controller is blocking requests in ASP.NET MVC through jQuery

我剛剛開始在我的項目中使用 AsyncController 來處理一些長期運行的報告。 當時看起來很理想,因為我可以開始報告,然后在等待報告返回並在屏幕上填充元素的同時執行一些其他操作。

我的控制器看起來有點像這樣。 我嘗試使用線程來執行我希望可以釋放控制器以接受更多請求的長任務:

public class ReportsController : AsyncController
{
    public void LongRunningActionAsync()
    {
        AsyncManager.OutstandingOperations.Increment();

        var newThread = new Thread(LongTask);
        newThread.Start();
    }

    private void LongTask()
    {
        // Do something that takes a really long time
        //.......

        AsyncManager.OutstandingOperations.Decrement();
    }

    public ActionResult LongRunningActionCompleted(string message)
    {
        // Set some data up on the view or something...

        return View();
    }

    public JsonResult AnotherControllerAction()
    {
        // Do a quick task...

        return Json("...");
    }
}

但是我發現,當我使用 jQuery ajax 請求調用 LongRunningAction 時,我在此之后發出的任何進一步請求都會備份在它后面並且在 LongRunningAction 完成之前不會被處理。 例如,調用 LongRunningAction 需要 10 秒,然后調用 AnotherControllerAction 不到一秒。 AnotherControllerAction 只是在返回結果之前等待 LongRunningAction 完成。

我還檢查了 jQuery 代碼,但如果我專門設置“async: true”,這仍然會發生:

$.ajax({
    async: true,
    type: "POST",
    url: "/Reports.aspx/LongRunningAction",
    dataType: "html",
    success: function(data, textStatus, XMLHttpRequest) { 
           // ...
        },
    error: function(XMLHttpRequest, textStatus, errorThrown) { 
       // ...
    }
});

目前我只需要假設我使用不正確,但我希望你們中的一個人能清除我的心理障礙!

這里有兩個問題。 首先是您的控制器不是真正的異步。 啟動 ThreadPool 線程來執行工作通常比僅在操作方法本身內執行所有操作具有更差的性能特征,因為您仍在從 ASP.NET(它只共享 CLR ThreadPool)獲取 ThreadPool 資源,您現在強制 CLR 和操作系統處理線程。 有關詳細信息,請參閱http://msdn.microsoft.com/en-us/library/ee728598.aspx#choosing_synchronous_or_asynchronous_action_methods 基本上,該鏈接歸結為,如果您不能將 I/O 完成端口用於異步操作,那么您不太可能看到性能提高。

第二個問題是 ASP.NET MVC 對所有請求都采用 Session 鎖定。 單個 Session 中的多個請求將始終被序列化,否則如果一個控制器寫入 Session 而另一個控制器試圖讀取它,則用戶的 Session 可能會損壞。 有關上下文和解決方法,請參閱http://forums.asp.net/t/1501623.aspx MVC 2 Futures 有一種禁用此鎖的方法; 它也可能包含在 MVC 3 中。 有關這方面的更多信息,請參閱鏈接

Acutally 問題在於 this.HttpContext.Session,因為它被鎖定了,如果你在 AsyncController 中的會話中寫入任何內容,你應該避免它並使用 this.HttpContext.Application - 這將解決問題,我有同樣的問題,試試我們

暫無
暫無

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

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