如果我使用会话,为什么控制器线程被阻止?

时间:2013-04-25 11:35:50

标签: asp.net asp.net-mvc asp.net-mvc-3 controller asynccontroller

我有一个非常简单的控制器:

  public class HomeController : Controller
    {
        public ActionResult Index()
        {
            Session["SomeData"] = "123";
            return View();
        }

        [HttpPost]
        public ActionResult LongTest()
        {
            Thread.Sleep(5000);
            return Json(new { Text = DateTime.Now.ToString("hh:mm:ss.fff") + " - LongTest"});
        }

        [HttpPost]
        public ActionResult CantAnswer()
        {
            return Json(new { Text = DateTime.Now.ToString("hh:mm:ss.fff") + " - CantAnswer"});
        }
    }

我以这种方式从客户端使用这些方法:

<script type="text/javascript">
    $(document).ready(function () {
        $('#btnLongOperation').click(function () {
            $.post("/Home/LongTest", null, function (data) {
                $('#result').text(data.Text);
            }, "json");
        });

        $('#btnWnotWork').click(function () {
            $.post("/Home/CantAnswer", null, function (data) {
                $('#result').text(data.Text);
            }, "json");
        });
    });
</script>
<div>
    <input id="btnLongOperation" type="button" value="Long operation"/>
    <input id="btnWnotWork" type="button" value="Won't work"/>
</div>
<div id="result">

如果我单击第一个按钮然后不等待5秒钟,请单击第二个按钮,我的第二个动作将不会被调用。 如果在Init方法中使用session删除字符串,您将看到可以在不等待彼此的情况下调用操作。但是,一旦使用会话对象,您将看不到第二个操作的结果,直到第一个操作完成。 谁能解释一下asp.net mvc的这种行为?

2 个答案:

答案 0 :(得分:2)

这是由会话锁定引起的。从本质上讲,每个使用会话状态的请求都会对其进行锁定,直到完成读取为止。在上一个请求释放锁定之前,后续请求无法访问Session

这样做的目的是确保会话数据的完整性。例如,如果请求A需要写入会话并请求B需要读取,但请求是同时发出的,会发生什么? B读取的数据是不可预测的,因为您无法知道它是在写入前还是在写入后。

请阅读此处了解更多信息:

http://www.timvasil.com/blog14/post/2008/04/16/Handling-multiple-simultaneous-requests-from-a-user-in-ASPNET.aspx

答案 1 :(得分:0)

您可以将异步控制器用于不同的行为。见link