Почему поток контроллера блокируется, если я использую сеанс?

У меня довольно простой контроллер:

  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 секунд, нажму вторую кнопку, мое второе действие не будет вызвано. Если вы удалите строку с использованием session в методе Init, вы увидите, что действия можно вызывать, не ожидая друг друга. Однако, как только вы используете объект сеанса, вы не увидите результат второго действия, пока первое не будет завершено. Кто-нибудь может объяснить это поведение asp.net mvc?

2 ответа

Решение

Это вызвано блокировкой сеанса. По сути, каждый запрос, использующий состояние сеанса, блокирует его до тех пор, пока он не завершит чтение. Последующие запросы не могут получить доступ Session пока предыдущий запрос не снимет блокировку.

Целью этого является обеспечение целостности данных сеанса. Например, что произойдет, если запрос A необходимо будет записать в сеанс, а запрос B необходимо прочитать, но запросы будут выполнены одновременно? Данные, которые B читает, непредсказуемы, так как у вас нет возможности узнать, будут ли они до или после записи.

Читайте здесь для получения дополнительной информации:

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

Вы можете использовать асинхронные контроллеры для различного поведения. Смотрите эту ссылку

Другие вопросы по тегам