State Management & Caching
Some Server-side Options for Maintaining State
Application - store state applicable to all users
Cache - store state for every user, expiration can be set, can set dependencies regarding expiration
Database-driven Session - store session objects using SQL server
Client-side Options for Maintaining State
Control State - provides state for control
Cookie - store state directly in file system of client, client can reject cookies
Hidden Field - store state directly in page markup
querystring - store state in URL
View State - encode state within page's markup
Available Session Modes
InProc - session state is in-process with ASP.NET worker process, default
Off - no session is made available
StateServer - session state is stored on an out of process server
SQLServer - session state is stored on an out of process SQL server
Running Sessions In-Process
provides best performance
requires server affinity
state will be lost if app or server restarts
    <sessionState
        mode="InProc"
        cookieless="false"
        timeout="20" />
Running Sessions Out of Process
uses Windows service named ASPState
start service using command prompt
    C:\Windows\Microsoft.NET\Framework\v4.0.30319\net start aspnet_state
setting session object to use StateServer option with defaults
    <sessionState
        mode="StateServer"
        stateConnectionString="tcpip=127.0.0.1:42424"
        sqlConnectionString="data source=127.0.0.1;user=sa;password="
        cookieless="false"
        timeout="20" />
Maintaining Sessions on SQL Server
same as StateServer mode except use SQL server
run install script
    C:\Windows\Microsoft.NET\Framework\v4.0.30319\OSQL localhost -U sa -P pwd -I InstallSqlState.sql
-U : assigned user name
-P : password
    <sessionState
        mode="SQLServer"
        stateConnectionString="tcpip=127.0.0.1:42424"
        cookieless="false"
        timeout="20" />
Best Performance Using Sessions
declare on each page how the page is to deal with Session object
   <%@ Page language="C#" EnableSessionState=&"True" CodeFile="Default.aspx.cs" Inherits="_Default" %>
EnableSessionState options
True - default, full access to Session object
False - no access to Session object
ReadOnly - read-only access to Session object
Working with Output Caching
output caching saves post-rendered content so that it will not have to be regenerated for subsequent requests
    <%@ OutputCache Duration="60" VeryByParam="None" %>
Duration - number of seconds a page is stored in the cache
VaryByParam - determines which versions of the page are cached
output cache directives
VaryByParam
specifies which querystring params cause a new version of the page to be cached
     <%@ OutputCache Duration="90" VeryByParam="pageId;subPageId" %>
each page with different pageId-subPageId pairings will be cached
     <%@ OutputCache Duration="90" VeryByParam="*" %>
each different querystring results in a page being cached
VaryByHeader
works off of the different HTTP headers
     <%@ OutputCache Duration="90" VeryByParam="*" VeryByHeader="User-Agent" %>
could multiply into 1000s of different versions
VaryByControl
use with complicated UserControls that render a lot of HTML but don't change often
     <%@ OutputCache Duration="2592000" VeryByControl="comboBoxOfCountries" %>
VaryByCustom
value of VaryByCustom is passed to GetVaryByCustomString method which is added to Global.aspx.cs
method called each time the page is requested
a different version of the page is cached for each different value the method returns
page's cache directive
    <%@ OutputCache Duration="90" VaryByParam="pageId,subpageId" VaryByCustom="prefs" %>
with method from Global.aspx.cs
    public override string GetVaryByCustomString(HttpContext context, string arg)
    {
        if(arg.ToLower() == "prefs")
        {
            HttpCookie cookie = context.Request.Cookies["Language"];
            if(cookie != null)
            {
                return cookie.Value;
            }
            return base.GetVaryByCustomString(context, arg);
        }
    }
caching is ASP.NET is a trade-off between CPU & memory
in last example the number of possible cache items can be determined by
    cacheItems = (number of pageIds) * (number of subPageIds) * (number of possible languages)
with 10 potential page IDs, five potential subpage IDs & 4 possible languages there can be 200 versions of the page to be cached
need to consider resource expense difference between caching and building a page
Extending <outputCache>
can extended how outputCache directive works
need to create custom output-cache provider
derived type must override the base class' Add, Get, Remove & Set methods
configuring for custom provider in web.config or machine.config
    <caching>
        <outputCache defaultProvider="AspNetInternalProvider">
            <providers>
                <add name="myCustomProvider" 
                     type="foo.bar.CustomProvider, CustomProvider" />
            </providers>
        </outputCache>
    </caching>
cache directive
    <%@ OutputCache Duration="90" VaryByParam="pageId,subpageId" providerName="myCustomProvider" %>
Partial Page (UserControl) Caching
cache only specific blocks of web page
achieved by caching user controls
modular design required
by default user controls are cached on a per page basis
change by using Shared attribute
    <%@ OutputCache Duration="90" VaryByParam="pageId,subpageId" Shared="true" %>
cached user control exists only for the first request
if HTML is retrieved from the OutputCache the control does not exist on the .aspx page
PartialCachingControl is created and acts as proxy
    protected void Page_Load()
    {
        if(PossiblyCachedControl != null)
        {
            // code to manipulate control
        }
    }
.NET 4's New Object Caching Option
what was in System.Web.Caching has be refactored into System.Runtime.Caching
lets other app types use caching without the need for System.Web dll
Caching Web Services
can cache SOAP responses
    [WebMethod(CacheDuration=60)]
    public string GetServerTime()
    {
        return DateTime.Now.ToLongTimeString();
    }
Hardware Considerations
Number of Outbound HTTP Connections
<configuration>
        <system.net>
            <connectionManagement>
                <add name="www.subdevo.com" maxconnection="5" />
                <add name="*" maxconnection="4" />
            </connectionManagement>
        </system.net>
    </configuration>
default maxconnection is 2
recommended number is 12 times the number of processors
Thread Pool
ASP.NET app uses threads from .NET thread pool
settings in machine.config determine some limits in how ASP.NET will manage the number of threads it can deal with
machine.Config & <processModel> Section
maxIoThreads attribute specifies the number of I/O threads within .NET thread pool
default value is 20
change value to 100
value automatically multiplied by the number of CPUs detected
maxWorkerThreads attribute specifies maximum number of worker threads in the ASP.NET worker process thread pool
default value is 20
change value to 100
value automatically multiplied by the number of CPUs detected
machine.Config & <httpRuntime> Element
minFreeThreads attribute specifies number of free threads that ASP.NET guarantees to be available
default is 8
recommended number is 88 times the number of CPUs on the server
minLocalRequestFreeThreads attribute controls number of free threads dedicated for local request processing
default value is 4
recommended number is 76 times the number of CPUs on the server
n4jvp.com