Performance Tuning and Optimizing ASP.NET Applications

ASP.NET provides a wide range of session state management capabilities, which allows for the dedicated storage and retrieval of user -specific information. Web applications are built on Hypertext Transfer Protocol (HTTP), which is inherently a stateless protocol. Web servers cannot typically recognize when a set of requests originates from a single user. (The exception would be if the user has a unique Internet Protocol that the Web application can reference from the HTTP Headers collection). This limitation makes it challenging to tailor a Web application experience to a single user. Personalized application sessions can usually only occur if the Web server retains session-specific information between requests . This process typically requires infrastructure support from the Web server and participation from the client. The server and the client establish a unique reference number for the session, or session ID , which is typically stored in a cookie on the client machine. Cookies alone may also enable session management because they allow session-specific information to be retained in a text file on the client machine. Cookies pass between the client and server during requests, which enables the server to customize a response based on client-specific information.

But cookies will only get you so far because they are limited both in size and in the complexity of information they can store. Cookies are limited to 4KB in size and are only capable of storing strings. You must store complex information, such as an array or an ADO.NET DataSet, in more sophisticated ways on the server side.

Note

Some developers prefer to create custom session management code rather than using the Session object. One approach is to persist session information in hidden fields or in the Uniform Resource Locator (URL) querystring. An alternate approach is to store session information in a backend database and key the records using the session ID key that is automatically generated when you enable session state management. In these cases, neither the Web server nor the client requires direct session management support.

There is actually a dual challenge to retaining and providing session-specific information. On the one hand, there is the challenge of how to retain and procure the information. And on the other hand, there is the challenge of how to do it quickly . Users will not appreciate their richly tailored individual experience if it requires them to wait for long periods of time between requests to the Web application.

Managing Session State in Classic ASP

Session state management was available in classic ASP, but it was much maligned for four important reasons:

Classic ASP developers use their skills to overcome these limitations as best they can. An especially popular approach is to retain all session information in a dedicated database, using the session ID as a primary key for referencing the information. This approach is not without its performance implications because database calls are slower than pulling data from memory. But the performance hit is worthwhile given that data is guaranteed to be available, especially from clustered SQL Servers, which are highly available. Of course, database server crashes will interrupt access to data. However, developers can greatly reduce the likelihood of crashes through a combination of reliable database software (SQL Server!) and fail-over measures, such as clustering database servers.

Managing ASP.NET Session State

ASP.NET addresses the limitations of classic ASP in the following ways:

In the "Understanding Session State Modes" section, we examine the various ASP.NET session state modes in detail. In addition, we discuss the performance implications of each mode. Clearly, there are performance implications when you require a server to manage session information. This task is an additional burden on the server and requires it to allocate valuable resources, both in terms of memory and processor utilization. The key is to pick a session state mode that provides the best session management for your application with the lowest overhead. That is, you must pick a mode that offers the optimal balance between performance and reliability for your particular state management requirements.

Configuring and Using ASP.NET Session State

Session state is enabled by default for a new ASP.NET project and is set to InProc (in-process) mode (described next ). You configure session state in the Machine.config and Web.config files using the <sessionState> element:

<sessionState mode=" OffInProcStateServerSQLServer" stateConnectionString="tcpip=127.0.0.1:42424" sqlConnectionString="server= machineName\sqlServer;uid=sa;pwd=;" cookieless="truefalse" timeout="20" />

In this example, the pipe symbol () indicates a mutually exclusive choice of options, and the connection string and timeout properties have default examples. Note that the Web.config file is case sensitive, so make sure you type all mode values using the correct case. "InProc" is a valid mode value, but "Inproc" is not. There is no special user interface (UI) for the Web.config file; otherwise this detail would be taken care of for you.

The minimum required <sessionState> attributes are mode , cookieless , and timeout (set in minutes). The stateConnectionString attribute is only required when the session mode is StateServer. Similarly, the sqlConnectionString attribute is only required when the session mode is SQLServer.

You can further configure session state at the individual page level using the EnableSessionState attribute of the @ Page directive:

<%@ Page EnableSessionState=" TrueFalseReadOnly" %>

If the attribute value is "True," then either a new session will be created or an existing session will be used. If the value is "False," then no new session will be created and no session values may be accessed on the page. If the value is "ReadOnly," then session values may be retrieved, but not modified.

Understanding Session State Modes

ASP.NET provides four modes for managing session state on the server:

Let's discuss each of the modes in turn , excluding the Off mode, which warrants no further explanation.

Using InProc Session State

The InProc mode is the default mode for session state and is equivalent to what classic ASP provides. This mode is the easiest to configure and only requires you to update the Web.config file:

<sessionState mode="InProc" cookieless="false" timeout="20" />

The advantages of the InProc mode are as follows :

The disadvantages of the InProc mode are as follows:

The InProc mode is an excellent choice if the session items are modest in size and you are not concerned about potentially losing session items and having to re-create them. E-commerce applications, for example, cannot afford to lose session data. However, other applications can use Session objects to reduce redundant database calls that would return duplicate information. These applications can easily re-create session items if they are lost.

Using StateServer Session State

The StateServer mode provides out-of-process session storage and management. This mode stores session items in a dedicated process managed by an NT service called ASP.NET State Service . You configure the StateServer mode in a two-step process. First, you update the Web.config file:

<sessionState mode="StateServer" stateConnectionString="tcpip=127.0.0.1:42424" cookieless="false" timeout="20" />

Next, you have to start the ASP.NET State Service because its default startup type is manual. Open the MMC snap-in from the Windows Start menu button by selecting Start Programs Administrative Tools Services.

Highlight the ASP.NET State Service entry, as shown in Figure 4-1, and click the Start button. Alternatively, you can right-click the entry and select Start from the pop-up menu.

Figure 4-1: The ASP.NET State Service

If you forget to start the service but you update the Web.config file, then your application will throw the following error:

System.Web.HttpException: Unable to make the session state request to the session state server. Make sure that the ASP.NET State service is started and that the client and server ports are the same.

The advantages of the StateServer mode are as follows:

The disadvantages of the StateServer mode are as follows:

The StateServer mode is often the worst choice you can make for managing session state. The cost of marshaling data across process boundaries is high, even if the size of the data is small. If you must access Session data from multiple servers, then SQLServer mode is often a better choice.

In ASP.NET 1.1, by default, only the local machine can connect to its ASP.NET State Service. You can grant non-local machines access to the State Service via a registry setting. This is an improvement over ASP 1.0, which did not restrict access to the StateServer mode from any machine.

Using SQLServer Session State

The SQLServer mode provides out-of-process session storage and management using a SQL Server database. You configure the SQLServer mode in a two-step process. First, you update the Web.config file:

<sessionState mode="SQLServer" sqlConnectionString="server= machineName\sqlServer;uid=myid;pwd=123;" cookieless="false" timeout="20" />

You have some flexibility in the format of the SQL connection string. You could use the following alternate format:

<sessionState mode="SQLServer" sqlConnectionString="data source= machineName\sqlServer; user id=myid;password=123;" cookieless="false" timeout="20" />

Note that the connection string does not include a database name. In fact, the application will generate a runtime error if you include a specific database name in the connection string. For security purposes, you may prefer to use a trusted connection in place of specifying SQL credentials in the database connection string. (Chapter 3, "Writing Optimized Data Access Code," describes SQL Server trusted connections in detail.)

Next, you need to run the SQL batch script that creates the SQL Server session state database:

  1. Open SQL Query Analyzer.

  2. Open the InstallSqlState.sql script in a new window. The script is located at %windir%\Microsoft.NET\Framework\%version% , where %version% is a folder that is named equal to the current installed version of the .NET Framework.

  3. Execute the SQL script in Query Analyzer.

The script creates a new database called ASPState , which contains a number of stored procedures for writing to, and reading from, the tempdb database. When a user assigns a session item, the information is inserted into a temporary table in the tempdb database. The new record includes an expiration timestamp that is equivalent to the < sessionState> element's timeout attribute value, in Web.config .

The advantages of the SQLServer mode are as follows:

The disadvantages of the SQLServer mode are as follows:

The SQLServer mode is typically your only choice for session state if you need to guarantee that the session information will be durable. The exception would be if your ASP.NET application stores small strings, and you are willing to persist this information in cookies on the individual client machines. The SQLServer mode is an excellent combination of performance and durability, and it will typically have limited impact on the scalability of an ASP.NET application. This is provided that the session items are modest in size and the number of session reads and writes remains reasonable. The SQLServer mode may not be a good choice if you are persisting large amounts of data, especially in combination with complex object types, such as the DataSet object. The process of serializing information to and from the database is extremely fast for a smaller number of users. But you are likely to notice a measurable delay if your application makes a high number of concurrent requests to the database, especially for larger amounts of information.

Analyzing Session State Performance

We have all heard about the supposed performance implications of using Session objects, but rarely do we see actual performance numbers in print. There is probably a good reason for this ”namely, that no published set of numbers really applies to your application. But there is value in looking at the relative performance numbers for a simple ASP.NET Web page that retrieves data from a SQL Server database. ASP.NET introduces a new and unfamiliar set of session management options, and it is interesting to look at how each mode performs relative to the others.

Visual Studio .NET Enterprise Edition provides a tool called Microsoft Application Center Test (ACT), which is a stress test tool for Web applications. The tool allows you to record a Web session and then execute it for multiple simulated users. ACT provides summary statistics and performance counter numbers for the test runs. These metrics enable you to analyze performance and scalability issues with your application. Chapter 7, "Stress Testing and Monitoring ASP.NET Applications," discusses how ACT works in great detail. For now, show simulations for an increasing number of concurrent browsers and measure three important performance and scalability counters:

Processor utilization is another important metric because it indicates whether your hardware is a limiting factor to your application's scalability. This metric factors into Transaction Cost Analysis (TCA), which provides a quantitative measure of the processing cost of your application for a specific user load. Note that TCA is not a part of this chapter's load testing because our purpose is to study the relative performance of each session state mode. However, Chapter 7, "Stress Testing and Monitoring ASP.NET Applications," discusses it in detail.

ACT also provides a summary of the HTTP Errors count, which is important because performance metrics are only relevant when a significant percentage of the requests have been successfully processed . As the number of concurrent browsers increases, the chance for errors increases as well. A successful request will return an HTTP response code of 200. ACT will commonly return two additional response codes:

Response code 403 is frequently returned for higher numbers of concurrent browsers. We do not consider performance numbers meaningful unless greater than 97.5 percent of the requests are fulfilled successfully. For this reason, in the following performance test, we ignored all test runs with greater than 10 concurrent browsers.

Sample Web Page with Session State

The sample Web "application" is a single Web page called ap_SalesQueryWithSession.aspx , which executes a stored procedure in the Northwind database and binds the resulting DataSet to a DataGrid on the page. Specifically, the page executes the [Employee Sales By Country] stored procedure, which accepts two input parameters: @BeginningDate and @EndingDate . Figure 4-2 shows the Web frontend screen for this stored procedure.

Figure 4-2: Using session state

The first time that the page executes, it retrieves a DataSet directly from the database. This DataSet gets bound to the DataGrid and then assigned to a Session object. In addition, the search parameters are persisted directly to view state so that they are available for comparison purposes. On subsequent requests, the code compares the current textbox values with the values in view state. If they are the same, then the code attempts to retrieve the DataSet from the Session object. If they are different, then the code executes a fresh database request.

This logic is handled inside of the BindDataGrid() function, as shown in Listing 4-1.

Listing 4-1: The BindDataGrid() Function

Private Sub BindDataGrid() Dim objDB As Apress.Database Dim arrParams() As String Dim sqlDS As DataSet Dim blnRefreshDS As Boolean = False Dim strJSScript As String = False ' Retrieve the connection string from Web.config Dim strConn As String strConn = ConfigurationSettings.AppSettings("ConnectionString") Try ' Did the search criteria change? If viewstate("BeginningDate") <> Me.ap_txt_beginning_date.Text Then _ blnRefreshDS = True If viewstate("EndingDate") <> Me.ap_txt_ending_date.Text Then _ blnRefreshDS = True ' Look for an existing DataSet object in a session variable sqlDS = CType(Session("sqlDataView"), DataSet) If sqlDS Is Nothing Then blnRefreshDS = True If blnRefreshDS Then ' Step 1: Instance a new Database object objDB = New Apress.Database(strConn) ' Step 2: Execute [Employee Sales By Country] arrParams = New String() { _ "@Beginning_Date", Me.ap_txt_beginning_date.Text, _ "@Ending_Date", Me.ap_txt_ending_date.Text} sqlDS = objDB.RunQueryReturnDS("[Employee Sales By Country]", _ arrParams) Session("sqlDataView") = sqlDS ' Assign DataSet to Session object ' Persist the search parameters in ViewState, for future comparison viewstate("BeginningDate") = Me.ap_txt_beginning_date.Text viewstate("EndingDate") = Me.ap_txt_ending_date.Text End If ' Bind the DataView to the DataGrid DataGrid1.DataSource = sqlDS DataGrid1.DataBind() Catch err As Exception ' Report the error in a JavaScript alert strJSScript = "<SCRIPT LANGUAGE='JavaScript'>alert('"& _ err.Message"');</SCRIPT>" RegisterStartupScript("JSScript1", strJSScript) Finally objDB = Nothing End Try End Sub

 

Note that Listing 4-1 uses a wrapper function called RunQueryReturnDS() , which is a member of a custom data access component that encapsulates ADO.NET database calls. You can view the code listing for this component in the sample project that accompanies this chapter.

Stress Testing with Session State

We stress tested the sample page in four groups of tests: one group for each of the four session state modes. We performed the testing within each group as follows:

  1. We configured the page for one of the session state modes: Off, InProc, StateServer, or SQLServer.

  2. ACT recorded a Web browser session with three steps:

    1. Load ap_SalesQueryWithSession.aspx into the browser for InProc, StateServer, and SQLServer modes. For Off mode, load ap_SalesQueryWithDataSet.aspx .

    2. Enter a Beginning Date of 01/01/1992 and an Ending Date of 01/01/2002.

    3. Click the Submit Query button twice: first, to retrieve a DataSet from the database and, second, to retrieve the DataSet from the Session object.

  3. The recorded script ran three times, one time each for one, five, and 10 concurrent browsers. The script ran for a 35-second interval with a five-second warm-up period.

The database returned 809 records per query for the time period from 01/01/1992 to 01/01/2002. ACT generated from roughly 600 to 900 connections per test during the 35-second testing interval, depending on the session mode. This means that the tests created anywhere from 200 to 450 Session objects during the testing interval.

We executed the tests in two groups of runs with different architectures:

The Group A tests represent better testing practices because the architecture spreads the processing burden between multiple servers. We ran the Group B tests because we could not otherwise generate memory usage numbers for different session state modes.

Before proceeding, we should point out that, in reality, you would likely not design a Web application to have tens to hundreds of session-stored data sets. The ACT tests represent unusually stressful conditions that would not likely be duplicated in the field because you would make a different design decision to avoid this situation. But this is, after all, what stress testing is all about.

Analyzing the Stress Testing Results

By session mode, Table 4-1 shows the change for Group A in the all-important Time To Last Byte (TTLB) parameter as the number of concurrent browsers increases. The numbers are normalized per 100 requests. You will recall that this parameter is a key indicator of application scalability.

Table 4-1: Normalized TTLB by Session State Mode (in Milliseconds per 100 Requests)

CONCURRENT BROWSERS

MODE = OFF

MODE = INPROC

MODE = STATESERVER

MODE = SQLSERVER

1

7.81

4.54

8.27

8.47

5

28.28

20.25

27.25

29.29

10

89.38

46.08

77.29

85.11

The TTLB numbers are similar for Off, StateServer, and SQLServer modes. However, the numbers are lower for InProc mode by up to a factor of two. This number becomes important when the Web server is under heavy load. A lower TTLB number translates into less latency ”that is, more requests serviced per second. The testing results indicate this, as shown in Table 4-2, which presents Group A average request rates for each of the session state modes.

Table 4-2: Average Requests per Second by Session State Mode

CONCURRENT BROWSERS

MODE = OFF

MODE = INPROC

MODE = STATESERVER

MODE = SQLSERVER

1

18.86

24.17

18.31

18.11

5

21.66

25.74

21.54

21.34

10

17.23

23.8

18.11

17.6

These numbers may not look very different, but they can translate into a dramatically different number of total serviced requests. For example, over the course of the 35-second testing interval with 10 concurrent users, the Off mode serviced 603 total requests, and the InProc mode serviced 833 total requests.

Based on these numbers, the total number of serviced requests, from highest to lowest, is as follows: InProc, StateServer, SQLServer, Off.

This sequence should sound entirely logical: InProc mode is fastest because it operates in memory and on the same worker process as the application. StateServer mode is the next fastest because it also operates in memory, although you take a responsiveness hit for the time it takes to marshal session data across processes. SQLServer is the next fastest because it takes time to exchange session information with the database. Finally, the Off mode is the least responsive because every response must be regenerated freshly.

One of the knocks against classic InProc session variables is that they are scalability killers. They exhaust server resources rapidly as the number of concurrent users increases. This is a double hit when you consider that the Web server could be using some of this memory for caching, which would help service requests even faster by avoiding a complete re-creation of the response. In fact, session variables continue to use server resources, even if the user is not actually storing any session-specific information. Even a lightly used session variable continues to consume server resources. The overall result is that the Web server services fewer requests as the number of concurrent users increases.

The numbers in Table 4-2 appear to verify this trend, although with an interesting twist. Each mode services the most requests for five concurrent users but a fewer number for one user and for 10 concurrent users. Figure 4-3 shows a graph of the Group A average requests per second by session state mode.

Figure 4-3: Group A ” Average requests/sec by session state mode

This " triangular trend" indicates that five concurrent users receive better responsiveness than one concurrent user. This trend may reflect the influence of SQL Server, which caches data pages for successive requests, and SQL connection pooling, which makes a set of connections readily available for multiple users. The number drops again for 10 concurrent users because it exceeds the pool number and begins to be high enough to burden the server.

A better measure of scalability changes is to look at the change in TTLB as the number of concurrent users increases. Figure 4-4 graphs the change in TTLB for each session state mode as the number of concurrent users increases. The numbers are normalized based on 100 requests to adjust for the fact that different session modes service different numbers of requests. For example, in the Group A tests, InProc mode serviced 846 total requests, and SQLServer mode serviced 634 total requests.

Figure 4-4: Group A ” Normalized TTLB by session state mode

The TTLB numbers shown in Figure 4-4 exhibit subtle differences, except for InProc mode, which experienced the lowest TTLB numbers. This indicates that the InProc mode can service a superior number of requests and remain more responsive than other session modes. We attempted to test more than 10 concurrent browsers, but the number of request errors exceeded 20 percent, which would not produce meaningful numbers for comparison.

Based on our limited data set, it is useful to look at relative growth rates in TTLB, as shown in Figure 4-5. The TTLB is normalized for each session mode, based on one concurrent user. For example, TTLB grows a factor of 10.05 for SQLServer mode as the number of concurrent browsers increases from 1 to 10.

Figure 4-5: Group A ” Normalized TTLB growth by session state mode

The differences in the TTLB growth rates are subtle, and it is perhaps a stretch to infer patterns from them. However, based on these numbers, the growth rate in TTLB for each session mode from highest to lowest is as follows: Off, InProc, SQLServer, StateServer.

This trend indicates that the Off mode experiences the greatest growth in TTLB as the number of concurrent users increases. The InProc mode and the SQLServer mode experience lesser growth in TTLB, and the StateServer mode experiences the lowest. The results simply indicate the trend in TTLB growth and are not a replacement for actual stress testing and observation at higher user loads. These limited results simply indicate that responsiveness goes down as the number of concurrent browsers increases and that the Off mode experiences the greatest decrease in responsiveness. As the stock market mantra goes, current results are not an indication of future performance. In a similar sense, TTLB growth changes at low user loads may not indicate their behavior at higher (and more critical) user loads.

A further note of wisdom is that every system will experience bottlenecks at some level, whether it is related to the processor speed, to available memory, to network latency, or to the number of active threads being processed. Your goal must be to stay ahead of the curve by designing your system to manage its expected loads as efficiently as possible. Ultimately, performance tuning is important because it allows your system to handle higher loads without a redesign or without having to purchase bigger, more expensive hardware.

The other piece of the scalability puzzle is memory usage. We were unable to generate memory usage numbers for Group A tests because ACT could not bind to the remote Memory counter on the Web server (recall that ACT is running on a separate server from the Web server). However, ACT has no problem binding to the Memory counter on the same server. As a workaround, we ran an alternative set of tests on a single server (Group B).

Figure 4-6 shows the Group B normalized TTLB values, based on 100 requests. The result pattern is different from the equivalent Group A test. The SQLServer and StateServer modes experience much higher TTLB values, compared to the InProc and Off modes, by up to two orders of magnitude. This difference may reflect the greater processor burden on the single server. Simply put, with more demands on the processor, the SQLServer and StateServer modes suffered because they are more dependent on processor availability. We are not attempting to explain the numbers away, but we are simply presenting the TTLB test results so that you can keep them in mind when evaluating the memory usage results.

Figure 4-6: Group B ” Normalized TTLB by session state mode

Figure 4-7 shows actual memory usage by session mode where memory usage is defined as the percentage of committed bytes in memory (as compared to the total amount of memory available). This is an actual measure of memory usage on the server, and it reflects the level of burden that each session mode places on available server memory.

Figure 4-7: Group B ” Actual memory usage by session state mode

The InProc mode clearly uses the highest amount of memory, followed by the StateServer mode. The Off mode uses the least amount of memory, which is to be expected. The SQLServer mode falls somewhere in between, although it is interesting to note that its growth curve in memory usage is steeper than for other modes. It is unfortunate that ACT could not generate meaningful numbers with more than 10 concurrent browsers because it would be interesting to see where the trends continued .

Memory usage numbers are an important indication of how a session mode impacts server resources. But as with every counter, it only tells a part of the story. For example, from Figure 4-7 alone, you might infer that the InProc mode is a potential scalability killer because it exerts the highest burden on server memory. But then, consider that it services a far greater number of requests than the other modes. Increased memory usage may be a small price to pay for the far greater number of requests that you can service, compared to other session modes. Add to this the fact that the InProc mode experiences lower TTLB growth rates than other session modes (based on both Group A and Group B test results). The InProc mode suddenly appears to be an attractive option for managing session state.

In closing out this section, we want to emphasize its overall message, which is that session state performance is not as clear-cut as many texts would lead you to believe. For example, many texts brand the InProc mode as a guaranteed scalability killer that should always be avoided on heavily trafficked Web sites. Our tests have demonstrated that the picture is more complex because the InProc mode offers far superior performance in exchange for higher memory usage.

Of course, there are other considerations that go into choosing a session state mode. For example, if you must persist session state to disk or manage it in a Web farm, then InProc mode will not meet your needs, no matter how good or bad it may be. The previous section described the advantages and disadvantages of each session state mode and discussed the optimal usage scenarios for each mode.

The bottom line is that only you can decide which approach is best for your Web site. There is no set of test numbers that can ever tell the definitive story, and we ask you to keep this in mind and to possibly be inspired to extend our testing with your own.

Programming with Session State

Session objects provide a straightforward application programming interface (API) that is easy to code against. Table 4-3 summarizes useful Session object members .

Table 4-3: Session Object Members

MEMBER

DESCRIPTION

SessionID

This read-only property gets the unique session ID used to identify the session.

Timeout

This read-write property gets or sets the timeout period (in minutes) between requests before the session is terminated .

Keys

This read-only property gets a collection of the keys of all values stored in the session.

IsReadOnly

This read-only property gets a value indicating whether a session is read-only. You set this property at the individual page level using <%@ Page EnableSessionState=" ReadOnly" %> .

Add()

This method adds a new item to session state. Its syntax is Add(name As String, value As Object) .

Clear()

This method clears all values and references from session state.

Abandon()

This method cancels the current session. If the session gets reinitialized, then the user gets a new session with a different session ID. Session objects store information by associating an object reference with a named index, or key , as follows:

Session("[Name]") = [Object]

Or, alternatively:

Session.Add("[Name]", [Object])

Note

If you add a session variable that already exists, then the existing session variable will simply be updated with the new object or value. The previous object, or value, will be overwritten without a warning.

Recall that in .NET, all data types inherit from the System.Object type. This enables Session objects to store virtually any .NET data type with two important exceptions:

You can iterate through a collection of session keys using the following:

Dim objKey As [Object] For Each objKey in Session.Keys Console.WriteLn(objKey.Name) ' Write out the name of the key Next

Retrieving session values is as simple as assigning the stored object back to a local variable:

sqlDV = Session("sqlDataView")

This method implicitly casts the session reference to the appropriate data type. You need to do this step because the Session object stores its references as Object data types for maximum flexibility. An alternative to implicit casting is to explicitly cast the data type when the reference is retrieved:

Dim sqlDV As DataView sqlDV = CType(Session("sqlDataView"), DataView)

Explicit casting is always preferable to implicit casting. Once you have retrieved an object reference, you should always verify it was retrieved successfully before using it in code. The easiest way to do this is to execute the assignment and then check to see if the object exists:

sqlDV = CType(Session("sqlDataView"), DataView) If sqlDV Is Nothing Then ' Recreate the object End If

Finally, the Session object provides two event handlers for adding code when a session is first created and when it is abandoned . The "Understanding the Global.asax File" section discusses the Session_Start() and Session_End() event handlers in more detail.

Session State Management in Web Farms

ASP.NET makes it easy to manage session state in Web farms. The StateServer and SQLServer modes are equally good candidates for centralized session state management, so you need to decide which mode is right for your application. The StateServer mode may offer better performance than the SQLServer mode. However, the SQLServer mode guarantees that session state information will be durable. The StateServer mode cannot provide the same guarantee because it provides in-memory storage.

Keep in mind that you may not need a centralized State server in your Web farm. If you are using an IP redirector, such as Cisco's LocalDirector or F5 Network's BIGIP, then a client's requests get routed to the same server for the duration of their session. In this case, you can maintain session state on individual servers, using either the InProc or StateServer modes. You do run a risk that IP redirection may not always work. If a server crashes or becomes unavailable, then the client will be routed to another server, which will have no record of their session information. For this reason, you may want to consider using centralized session state management.

If you decide on using the StateServer mode, then you need to start the ASP.NET State Service on one of the servers in the Web farm. You must designate only one server in the Web farm for managing session state because you are proceeding on the assumption that there is no fixed redirection of requests in the Web farm. The advantage of this approach is its flexibility in being able to manage state for all servers in the Web farm. However, the disadvantage of this approach is that it creates a single potential point of failure. In exchange for flexibility, you run a higher risk that the State server may fail and be completely unavailable for all servers in the Web farm.

Next, you need to modify the Web.config file for each server in the Web farm to point to the centralized State server. For example:

<sessionState mode="StateServer" stateConnectionString="tcpip=127.0.0.1:42424" cookieless="false" timeout="20" />

Obviously, for this connection string to work, the State server must provide a fixed IP and must not use Dynamic Host Control Protocol (DHCP). If you decide on using the SQLServer mode, then you need to set up a central database server and run the SQL script that creates the ASPState database. Next, you need to modify the Web.config file for each server in the Web farm to point to the same SQL Server database. For example:

<sessionState mode="SQLServer" sqlConnectionString="server= machineName\sqlServer;uid=myId;pwd=myPwd;" cookieless="false" timeout="20" />

If the reliability of your session is of utmost importance, then you can implement state management on a cluster of multiple database servers so that no single point of failure exists.

This concludes the discussion of session state management. Next, turn your attention to the topic of application state management.

Категории