Learn more ASP.NET tricks from Karl Moore. In this installment, learn
what to do when Session_End doesn't work, spy on your Web host (checking uptime in .NET), stress test your Web applications, and learn about using .IsClientConnected for Long Processes.
Welcome to the fifth and final part of ASP.NET Secrets!
I'm Karl Moore and over the following half-a-dozen pages, we'll be wrapping up our look at building interactive sites with the following bundle of tricks, based on tips listed in my new book, VB.NET and ASP.NET Secrets:
- Using .IsClientConnected for Long Processes
- What to Do When Session_End Doesn't Work
- Spy on your Web Host: Checking Uptime in .NET
- Can It Cope?—Stress Testing your Web Apps
Of course, this may be the last part of the ASP.NET Secrets articles; however, it's only the eighth article in the entire .NET Secrets series of articles we're running. We still have .NET Data Secrets and Web Service Secrets to follow, starting in a couple weeks' time.
But that's all to come. For now... the ASP.NET secrets!
Using .IsClientConnected for Long Processes
If you're performing a long process or calculation behind a Web page, it's a good idea to periodically check whether your client is still connected. You may want to do this at set intervals in your code, or just before sending your results down to the browser.
You can do this through the innovatively titled function, Response.IsClientConnected. It'll return a True if the client is still connected to the server. If it isn't, you'll want to exit your code and run a Response.End.
What to Do When Session_End Doesn't Work
It's one of the most common complaints on the newsgroups: "Hey! My Session End event doesn't fire. The code I want to run when the Session finishes just never runs." And then you get the whiz kid that replies with: "It's a bug. You can't rely on it on that End event. Use another method."
Important note: the whiz kid is wrong.
If the code you've entered in your Global.asax file to run when the Session End event fires doesn't appear to be kicking in, there are just three things that could be at fault:
- You're not using InProc—The mode attribute of the <sessionState> element in your application Web.config file must be set to "InProc". If it isn't, the End event simply cannot fire.
- You're not using the Session—The Session End event can't fire if there's no Session to End. Are you sure your application is storing information through the Session object?
- Your code is flawed—There's an error somewhere in the code that responds to the End event. Try running your application in debug mode, with a short <sessionState> timeout attribute. Visit the page and then wait. Does the End event kick in? Does an error occur in your code?
There is quite seriously no other excuse for your code not running. There's no mysterious bug. There are no weird setup issues or reasons for not trusting the Session End event. It works, no excuses.
Spy on Your Web Host: Checking Uptime in .NET
Okay, so your host promises 99.999% uptime, but are they really delivering? Unless you're either checking every couple of seconds, or dishing out on some monitoring service, you really don't have much of an idea.
That is, until now.
ASP.NET Web pages served up through IIS are delivered through an ASP.NET "worker process" (aspnet_wp.exe). It's this file that executes your code and puts all the ASP.NET pieces together. If we could access this worker process, we may be able to look at how long it had been running, its current state—and perhaps even a history, showing previous instantiations of the worker process.
Well, you can. And the following snippet of code shows you exactly how:
Dim strReport As String
Dim objInfo As ProcessInfo = _
' Get time information
strReport = "ASP.NET was started at " & _
objInfo.StartTime.ToString & ". " & _
"It has been running for " & _
objInfo.Age.Days & " days, " & _
objInfo.Age.Hours & " hours and " & _
objInfo.Age.Minutes & " minutes. "
' Get other info
strReport = "The process ID is " & _
objInfo.ProcessID & ". " & _
"Current status is " & _
objInfo.Status.ToString & ". " & _
"Peak memory used was " & _
objInfo.PeakMemoryUsed & ". " & _
"Request count is currently " & _
objInfo.RequestCount & "."
It may look a little weird, but all we're doing here is retrieving a ProcessInfo object containing information about the current worker process. This is then formulated into a string using key properties and spurted out to the user, through Response.Write. Try it out—you'll be given an instant server status report.
The ProcessModelInfo class also has a GetHistory method, allowing you to retrieve information about previous instances of the aspnet_wp.exe process. It returns an array of ProcessInfo objects. Either use a For...Next loop to retrieve this information, or bind direct to a DataGrid.
There's also a technique for retrieving the amount of time your actual server has been running (not just the ASP.NET worker process). Simply nab the TickCount from the Environment class, which lists the number of milliseconds the machine has been running. After that, either perform a few simple calculations—or, slightly easier, convert it into a period of time (a TimeSpan object), then retrieve the appropriate properties. Here's my snippet of code that does exactly that:
Dim tsAge As TimeSpan = _
Dim intDaysUp As Integer = tsAge.Days
Dim intHoursUp As Integer = tsAge.Hours
Dim intMinsUp As Integer = tsAge.Minutes
Response.Write("The server has been up " & _
intDaysUp & " days, " & intHoursUp & _
" hours and " & intMinsUp & " minutes.")
Caption: ASP.NET only been running for 13 minutes? Sounds dodgy. Change your host.
Can It Cope?—Stress Testing Your Web Apps
It's the new face of that old, often-troublesome Web Application Stress Tool. It's a tool designed to see whether your site can stand up against heavy traffic. It's distributed with the Enterprise and Architect editions of Visual Studio .NET. It's the curiously christened... Application Center Test (ACT).
Here's how it works. You launch ACT and record a browser session, simulating a regular user. You may explore the site, do a little searching, upload a couple of files, whatever users typically do at your site. Then you get tell ACT to rerun that test over and over again, perhaps simultaneously and with great speed. When finished, you check out the results to see how both your server and ASP/ASP.NET applications stood up to being thrashed.
Start by launching ACT: Click Programs > Microsoft Visual Studio .NET > Microsoft Visual Studio .NET Enterprise Features > Microsoft Application Center Test. You'll see a bundle of existing samples. To record your own, right-click the "Tests" node and choose "New Test." Skipping through the wizard, select "Record a new test;" then click the button to "Start recording." An empty Internet Explorer browser window will appear.
Top Tip: Using a dial-up networking connection? It's poorly documented, but ACT won't record test sessions through a regular dial-up. In fact, even if you're recording on the http://localhost/ server whilst a dial-up connection is active in the background, it'll refuse to record. Yes, it's annoyingly picky: Try disconnecting and attempting once more.
Ensure you are not "Working Offline" (if so, uncheck this mode using the File menu); then start acting like a user: browse, log in, search. Play around for a minute or three. When you're done, stop using the browser window and return to ACT, clicking "Stop recording." Provide your test with a name, and then finish the wizard.
Your test should now appear under the list of "Tests." Select it and view the VBScript code generated for you. If you need to remove any unnecessary requests, simply comment out the call SendRequest# line in the Sub Main method at the bottom of your test script.
So, you have your test recorded. Now, let's look at its settings: right-click your test and select Properties. This is where you choose how far to push your application, selecting parameters such as how many simultaneous browser connections you want to simulate or how long you wish to run the test. You also can use the Counters tab to monitor certain parts of your system as the site is being accessed, potentially enabling you to track down bottlenecks. The Users tab also lets you specify a list of test users to log in to your site (however, this requires a little custom programming and a surf through the Help files). Click OK when finished.
When you're ready to begin, add any notes for this test in the top panel; then right-click your test and select Start Test. You'll be shown a summary as the whole thing churns away. If you're curious, you also can click "Show Details" for an instant graphical view of how it's all going.
After the test has finished, you'll probably want a detailed report as to how it all went. Click Close; then select the 'Results' node and highlight your test run. You should be presented with a graphical report showing how well your site handled the situation—or not, as the case may be. Here, you'll be able to see how many application requests per second the Web server was able to handle, how long it took the server to respond, and how much bandwidth you used per second.
If you chose to record Performance Counters, you should also be able to view data about how your machine handled itself, too. If you wish, you can check multiple tests to compare results. More information about analyzing the content in these reports can be found in the ACT help file under "Analyzing the Test Results."
If your site didn't hold up as well as you thought it should—reacting slowly and producing connection errors—you might want to start looking at how you can optimize your application a little more. For example, you may implement caching, rewrite inefficient code, distribute your application over multiple machines (a 'Web farm'), or simply upgrade your server.
No matter what the outcome, it's always good practice to stress test your application, in preparation for the real world. Because you never know when that next flood of visitors will be checking in...
Top Tip: If you have the urge, you can even use ACT directly from within Visual Studio .NET. When creating a new project, select Other Projects > Application Center Test Projects > ACT Project. From here, you can record a test then run it within VS.NET. You don't get the fancy user interface nor the handy samples, plus all the results are reported there and then in the Output window, but it's a potentially useful integration.
Click here for a larger image.
Caption: A little test I ran earlier with a bottle-necking application...
Coming up next time, in part one of .NET Data Secrets:
- Generating GUIDs in a Flash
- Making Your Own OLE DB Connection String Creator
- Cheating with SQL
- Finding the Last Identity Number Added
- Seven Steps to a Quick, Editable Windows Grid
See you then!
About the Author
Karl Moore is a technology author living in Yorkshire, England. He runs his own consultancy group, White Cliff Computing Ltd, and is author of two best-selling books exposing the secrets behind Visual Basic .NET. When he's not writing for magazines, speaking at conferences, or making embarrassing mistakes on live radio, Karl enjoys a complete lack of a social life. Check out Karl's newest book, Ultimate VB .NET and ASP.NET Code Book.
# # #