1

我有一個非常簡單的控制器:爲什麼我使用會話時控制器線程被阻塞?

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方法中使用會話刪除字符串,您將看到可以調用這些操作而無需等待對方。但是,一旦使用會話對象,您將看不到第二個動作的結果,直到第一個動作完成。 任何人都可以解釋這種行爲的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

0

您可以使用異步控制器的不同的行爲。看到這個link

相關問題