Asp.net mvc 中處理同一個session的並行請求的問題


首先來一個小的asp.net mvc 4的sample,代碼如下:

HomeController:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.SessionState;
namespace MvcApplication2.Controllers
{
    public class HomeController : Controller
    {
        //
        // GET: /Home/
        public ActionResult Index()
        {
            return View();
        }
        public ActionResult Test()
        {
            //這里為了測試執行了等待30秒的代碼,實際項目中會遇到
            //很多類似需要很長時間的情況,比如調用webservice,或者處理很大數據
            System.Threading.Thread.Sleep(30000);
            return View();
        }
    }
}

 

 Global.asax:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Http;
using System.Web.Mvc;
using System.Web.Optimization;
using System.Web.Routing;

namespace MvcApplication2
{
    // Note: For instructions on enabling IIS6 or IIS7 classic mode, 
    // visit http://go.microsoft.com/?LinkId=9394801

    public class MvcApplication : System.Web.HttpApplication
    {
        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();

            WebApiConfig.Register(GlobalConfiguration.Configuration);
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundleConfig.RegisterBundles(BundleTable.Bundles);
        }
        protected void Session_Start(object sender, EventArgs e)
        {
        }
    }
}

 

 

Views中的代碼省略。

這么簡單的程序如果我們運行會發現一個問題:當我打開瀏覽器打開兩個tab,先在一個tab中打開/Home/Test,這時這個tab會等30秒才能呈現頁面,在這期間我在另一個tab中打開 /Home/Index,只有等第一個tab30秒過后,第二個tab才能呈現/Home/Index。而這種情況如果在實際項目中會非常影響性能,比如我們如果需要訪問webservice耗用大量時間獲取一些數據,同時我們又要通過ajax發送請求去處理一個查詢,這時如果按照上面的做法,只能等待webservice方法執行完畢后才能處理ajax請求。(Note:這種情況只有在同一個session下存在,如果上面的操作不打開兩個tab而是換成兩個瀏覽器,類似情況不會發生)

 解決方案:

這里我們需要了解一下asp.net mvc 中的SessionState的作用:

在stackoverflow的一片文章記錄到:

Session state is designed so that only one request from a particular user/session occurs at a time. So if you have a page that has multiple AJAX callbacks happening at once they will be processed in serial fashion on the server. Going session-less means that they would execute in parallel.

大意就是Session state是用來將同一個session的請求按順序處理,如果需要並行處理則需要設置session-less。

 

如何設置SessionState呢?

mvc4中可以在controller上面加如下Attribute:(在System.Web.SessionState命名空間下)

[SessionState(SessionStateBehavior.ReadOnly)]

 

 mvc3加如下Attribute:

[ControllerSessionState(SessionStateBehavior.ReadOnly)]

 

 SessionStateBehavior四個選項中的區別:

  • Default – Same as Required.
  • Required – A full Session lock is taken, and requests to this controller are serialized.  This is the normal MVC behavior.
  • ReadOnly – A Session lock is not taken, and a controller can read values in Session, but it cannot modify the values in Session.  Requests to this controller will be parallelized.
  • Disabled – Session is unavailable within this controller, and attempts to use it will be met with an error.  Requests to this controller will be parallelized


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM