{"id":15305,"date":"2014-08-27T15:10:07","date_gmt":"2014-08-27T13:10:07","guid":{"rendered":"http:\/\/infozone.se\/?p=15305"},"modified":"2014-08-27T15:10:07","modified_gmt":"2014-08-27T13:10:07","slug":"handling-concurrent-access-asp-net-mvcs-session-state","status":"publish","type":"post","link":"https:\/\/www.infozone.se\/en\/latest-news\/handling-concurrent-access-asp-net-mvcs-session-state\/","title":{"rendered":"Handling concurrent access to ASP.NET MVC’s session state"},"content":{"rendered":"

How concurrent access to the session is handled<\/h2>\n

Access to the session state is per session exclusive, which means that a request to the session state applies an exclusive lock on the session object. Other requests trying to access the same session object concurrently will then have to wait until the first request has completed and released the lock. On the other hand, concurrent requests accessing different sessions can be handled concurrently.<\/p>\n

To illustrate the exclusive access to the same session state I\u2019ve created a simple MVC application with a controller that contains the action Work with the following setup:<\/p>\n

 [HttpGet]\n\n        publicActionResult Work()\n\n        {\n\n            Thread.Sleep(6000);\n\n \n\n            return Json(Session[\"user\"], JsonRequestBehavior.AllowGet);\n\n        }\n\nIn the client, three requests are calling the Work action trying to concurrently access session information:\n\n        $(function() {\n\n            var work = function(id) {\n\n                $.get('home\/work\/' + id, function() {\n\n                    console.log(arguments);\n\n                });\n\n            };\n\n \n\n            for (var i = 0; i < 3; i++) {\n\n                work(i);\n\n            }\n\n        });<\/pre>\n

 <\/p>\n

Inspecting the requests in firebug one can see that the total time to process these three requests is 18 seconds, as illustrated in the figure below. The first request locks the session and the two other requests waits for it to complete. When the first request has completed, the second request access the session and adds a new lock to it. And the chain continues.<\/p>\n

\"\"<\/p>\n

Overriding the session state<\/h2>\n

The example above contains no modifying operation to the session state and the session lock is just an unnecessary performance killer. Fortunately, it\u2019s possible to override and declare how the controller will treat the session state. This can be accomplished by decorating the controller with the SessionState attribute. The attribute takes the SessionStateBehaviour enumeration as an in parameter to the constructor. The enumeration has the following members:<\/p>\n

    \n
  • Disabled \u2013 The session state is disabled for all requests towards the controller.<\/li>\n
  • ReadOnly \u2013Read access to the session state is granted but the controller cannot update any session information. Requests towards a read-only session does not apply any locks to the session state.<\/li>\n
  • Required \u2013 Both write and reads access are granted for all requests.<\/li>\n
  • Default \u2013 ASP.NET uses the default logic to determine the session state for each request.<\/li>\n<\/ul>\n

    To show this in action, the controller from the previous example is now decorated with the SessionStateAttribute with ReadOnly access:<\/p>\n

       [SessionState(SessionStateBehavior.ReadOnly)]\n\n    publicclassHomeController : Controller<\/pre>\n

    The timeline now shows that there are no exclusive locks on the session and all requests are handled concurrently:<\/p>\n

    \"\"<\/p>\n

    Changing the session state behaviour conditionally<\/h2>\n

    The attribute might not be sufficient in all scenarios. It might be required to change the state of controllers conditionally. The controllers\u2019 session state behaviour can as well be set in a ControllerFactory\u2019s GetControllerSessionBehaviour method. To exemplify this, I\u2019ve created a controller factory that inherits from the DefaultControllerFactory and overrides the GetControllerSessionBehavior method.<\/p>\n

    The rule in this example is as follows: If no SessionStateAttribute has been added to the controller, use ReadOnly access (ReadOnly is now the default session state behaviour throughout the application).<\/p>\n

     <\/p>\n

     publicclassSessionStateControllerFactory : DefaultControllerFactory\n\n    {\n\n        protectedoverrideSessionStateBehavior GetControllerSessionBehavior(RequestContext requestContext, Type controllerType)\n\n        {\n\n            if (controllerType == null || !Attribute.IsDefined(controllerType, typeof (SessionStateAttribute)))\n\n            {\n\n                returnSessionStateBehavior.ReadOnly;\n\n            }\n\n           \n\n            \/\/ Use the default method to look up the actual value of the session attribute. It uses a cache for lookup\n\n            returnbase.GetControllerSessionBehavior(requestContext, controllerType);\n\n        }\n\n    }<\/pre>\n

    And register the new controller factory somewhere in the application start up:<\/p>\n

    ControllerBuilder.Current.SetControllerFactory(newSessionStateControllerFactory());<\/p>\n

    Summary<\/h2>\n

    Unnecessary locks to the session state can be avoided by declaring the intent of how a controller uses the session data. Here I\u2019ve showed how the intent can be declared using either the SessionState attribute or a controller factory. Try it out and let me know how it goes!<\/p>\n","protected":false},"excerpt":{"rendered":"

    How concurrent access to the session is handled Access to the session state is per session exclusive, which means that a request to the session state applies an exclusive lock on the session object. Other requests trying to access the same session object concurrently will then have to wait until the first request has completed […]<\/p>\n","protected":false},"author":2,"featured_media":23464,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[118],"tags":[],"class_list":["post-15305","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-blog"],"yoast_head":"\nHandling concurrent access to ASP.NET MVC's session state - Infozone - English<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.infozone.se\/en\/latest-news\/handling-concurrent-access-asp-net-mvcs-session-state\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Handling concurrent access to ASP.NET MVC's session state - Infozone - English\" \/>\n<meta property=\"og:description\" content=\"How concurrent access to the session is handled Access to the session state is per session exclusive, which means that a request to the session state applies an exclusive lock on the session object. Other requests trying to access the same session object concurrently will then have to wait until the first request has completed […]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.infozone.se\/en\/latest-news\/handling-concurrent-access-asp-net-mvcs-session-state\/\" \/>\n<meta property=\"og:site_name\" content=\"Infozone - English\" \/>\n<meta property=\"article:published_time\" content=\"2014-08-27T13:10:07+00:00\" \/>\n<meta name=\"author\" content=\"Eva-Katrine\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Eva-Katrine\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"3 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.infozone.se\/en\/latest-news\/handling-concurrent-access-asp-net-mvcs-session-state\/\",\"url\":\"https:\/\/www.infozone.se\/en\/latest-news\/handling-concurrent-access-asp-net-mvcs-session-state\/\",\"name\":\"Handling concurrent access to ASP.NET MVC's session state - Infozone - English\",\"isPartOf\":{\"@id\":\"https:\/\/www.infozone.se\/en\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.infozone.se\/en\/latest-news\/handling-concurrent-access-asp-net-mvcs-session-state\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.infozone.se\/en\/latest-news\/handling-concurrent-access-asp-net-mvcs-session-state\/#primaryimage\"},\"thumbnailUrl\":\"\",\"datePublished\":\"2014-08-27T13:10:07+00:00\",\"author\":{\"@id\":\"https:\/\/www.infozone.se\/en\/#\/schema\/person\/0d207ef1167f0800247368907c22564a\"},\"breadcrumb\":{\"@id\":\"https:\/\/www.infozone.se\/en\/latest-news\/handling-concurrent-access-asp-net-mvcs-session-state\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.infozone.se\/en\/latest-news\/handling-concurrent-access-asp-net-mvcs-session-state\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.infozone.se\/en\/latest-news\/handling-concurrent-access-asp-net-mvcs-session-state\/#primaryimage\",\"url\":\"\",\"contentUrl\":\"\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.infozone.se\/en\/latest-news\/handling-concurrent-access-asp-net-mvcs-session-state\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Hem\",\"item\":\"https:\/\/www.infozone.se\/en\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Handling concurrent access to ASP.NET MVC’s session state\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.infozone.se\/en\/#website\",\"url\":\"https:\/\/www.infozone.se\/en\/\",\"name\":\"Infozone - English\",\"description\":\"We Create Heroes\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.infozone.se\/en\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.infozone.se\/en\/#\/schema\/person\/0d207ef1167f0800247368907c22564a\",\"name\":\"Eva-Katrine\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.infozone.se\/en\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/20706a650402f90b216ccbbe6a90cfdb?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/20706a650402f90b216ccbbe6a90cfdb?s=96&d=mm&r=g\",\"caption\":\"Eva-Katrine\"},\"url\":\"https:\/\/www.infozone.se\/en\/latest-news\/author\/eva-katrine\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Handling concurrent access to ASP.NET MVC's session state - Infozone - English","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.infozone.se\/en\/latest-news\/handling-concurrent-access-asp-net-mvcs-session-state\/","og_locale":"en_US","og_type":"article","og_title":"Handling concurrent access to ASP.NET MVC's session state - Infozone - English","og_description":"How concurrent access to the session is handled Access to the session state is per session exclusive, which means that a request to the session state applies an exclusive lock on the session object. Other requests trying to access the same session object concurrently will then have to wait until the first request has completed […]","og_url":"https:\/\/www.infozone.se\/en\/latest-news\/handling-concurrent-access-asp-net-mvcs-session-state\/","og_site_name":"Infozone - English","article_published_time":"2014-08-27T13:10:07+00:00","author":"Eva-Katrine","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Eva-Katrine","Est. reading time":"3 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/www.infozone.se\/en\/latest-news\/handling-concurrent-access-asp-net-mvcs-session-state\/","url":"https:\/\/www.infozone.se\/en\/latest-news\/handling-concurrent-access-asp-net-mvcs-session-state\/","name":"Handling concurrent access to ASP.NET MVC's session state - Infozone - English","isPartOf":{"@id":"https:\/\/www.infozone.se\/en\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.infozone.se\/en\/latest-news\/handling-concurrent-access-asp-net-mvcs-session-state\/#primaryimage"},"image":{"@id":"https:\/\/www.infozone.se\/en\/latest-news\/handling-concurrent-access-asp-net-mvcs-session-state\/#primaryimage"},"thumbnailUrl":"","datePublished":"2014-08-27T13:10:07+00:00","author":{"@id":"https:\/\/www.infozone.se\/en\/#\/schema\/person\/0d207ef1167f0800247368907c22564a"},"breadcrumb":{"@id":"https:\/\/www.infozone.se\/en\/latest-news\/handling-concurrent-access-asp-net-mvcs-session-state\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.infozone.se\/en\/latest-news\/handling-concurrent-access-asp-net-mvcs-session-state\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.infozone.se\/en\/latest-news\/handling-concurrent-access-asp-net-mvcs-session-state\/#primaryimage","url":"","contentUrl":""},{"@type":"BreadcrumbList","@id":"https:\/\/www.infozone.se\/en\/latest-news\/handling-concurrent-access-asp-net-mvcs-session-state\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Hem","item":"https:\/\/www.infozone.se\/en\/"},{"@type":"ListItem","position":2,"name":"Handling concurrent access to ASP.NET MVC’s session state"}]},{"@type":"WebSite","@id":"https:\/\/www.infozone.se\/en\/#website","url":"https:\/\/www.infozone.se\/en\/","name":"Infozone - English","description":"We Create Heroes","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.infozone.se\/en\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/www.infozone.se\/en\/#\/schema\/person\/0d207ef1167f0800247368907c22564a","name":"Eva-Katrine","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.infozone.se\/en\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/20706a650402f90b216ccbbe6a90cfdb?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/20706a650402f90b216ccbbe6a90cfdb?s=96&d=mm&r=g","caption":"Eva-Katrine"},"url":"https:\/\/www.infozone.se\/en\/latest-news\/author\/eva-katrine\/"}]}},"acf":[],"_links":{"self":[{"href":"https:\/\/www.infozone.se\/en\/wp-json\/wp\/v2\/posts\/15305","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.infozone.se\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.infozone.se\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.infozone.se\/en\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.infozone.se\/en\/wp-json\/wp\/v2\/comments?post=15305"}],"version-history":[{"count":0,"href":"https:\/\/www.infozone.se\/en\/wp-json\/wp\/v2\/posts\/15305\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.infozone.se\/en\/wp-json\/"}],"wp:attachment":[{"href":"https:\/\/www.infozone.se\/en\/wp-json\/wp\/v2\/media?parent=15305"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.infozone.se\/en\/wp-json\/wp\/v2\/categories?post=15305"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.infozone.se\/en\/wp-json\/wp\/v2\/tags?post=15305"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}