c# - 异步 Controller 通过 jQuery 阻止 ASP.NET MVC 中的请求

标签 c# javascript asp.net-mvc-2 jquery

我刚刚开始在我的项目中使用 AsyncController 来处理一些长时间运行的报告。当时看起来很理想,因为我可以启动报告,然后在等待它返回并在屏幕上填充元素的同时执行一些其他操作。

我的 Controller 看起来有点像这样。我尝试使用一个线程来执行我希望可以释放 Controller 以接受更多请求的长期任务:

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 完成之前不会被处理。例如,调用需要 10 秒的 LongRunningAction,然后调用不到一秒的 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) { 
       // ...
    }
});

目前我只能假设我使用不当,但我希望你们中的一个能清除我的心理障碍!

最佳答案

这里有两个问题。首先是您的 Controller 不是真正的异步。启动 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 中的多个请求将始终被序列化,否则如果一个 Controller 写入 Session 而另一个 Controller 正在尝试读取它,则用户的 Session 可能会损坏。参见 http://forums.asp.net/t/1501623.aspx上下文和解决方法。 MVC 2 Futures 有一种禁用此锁定的方法;它也可能包含在 MVC 3 中。参见 Link有关这方面的更多信息。

关于c# - 异步 Controller 通过 jQuery 阻止 ASP.NET MVC 中的请求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2927726/

相关文章:

javascript - 将字符串从 Python 传递到 Javascript

javascript - 在 foreach 循环内切换类

javascript - 如何获取选项选定的数据标签

asp.net-mvc - ASP.NET MVC : generating action link with custom html in it

asp.net-mvc-2 - 使用Unity IoC的MVC2- Controller 如何解析?

c# - 查找 .NET 应用程序中的非托管内存泄漏

c# - 类与结构

c# - ASP.NET MVC 中的 NHibernate 上下文 session

c# - 将属性绑定(bind)到方法

c# - 在静态方法中初始化对象并使用 NSNotificationCenter 的内存泄漏