February 2005 - Posts
In our System.Threading talk we cover the impact of threading in an ASP.NET application and specifically how damaging to your applications scaleability it can be to call external systems with unpredictable performance characteristics. (eg. SQL-Server, WebServices, COM component, java, etc).
The problem here is you will be "hogging" your ASP.NET thread for the duration of the transaction. You may not feel this is a problem because you clearly can't return the page until this external transaction has completed so you may as well wait. You might even turn this into an async call so you can do something else in parallel however you still end up ultimately waiting for the remote system to complete before you can complete your page construction and return the page to the caller.
So why is this so bad?
Well the problem is you have a finite number of threads available in the Thread Pool to process page requests so if you are "hogging" them in your pages while you wait for an external system to respond you will be blocking other page requests.
To demonstrate this I knocked up two aspx pages; one which did nothing and another which spun up a new thread which waited for 30 seconds before completing.
When I ran my nothing page alone using ACT over 5 mins I got the following results:
Response Code: 200 - The request completed successfully. Count: 141,575 Percent (%): 100.00
When I ran my nothing page and my badly threaded page at the same time using ACT over 5 mins I got the following results (I started my thread page first which allowed it to grab all the available threads!):
Response Code: 503 - The service is temporarily overloaded. Count: 45,169 Percent (%): 99.92
Response Code: 500 - The server encountered an unexpected condition that prevented it from fulfilling the request. Count: 36 Percent (%): 0.08
So as you can see from the results above my badly threaded page completely blocked all activity on the web server for 5 whole minutes!
It is also worth noting that the processor utilisation during this period was almost zero so the web server was genuinely busy doing nothing!
I have included the source code for my badly threaded page below. In my example I use "raw" threads however remember the same applies to async calls to SQL Server, Web Services, etc. I think this is particularly important when using 3rd party Web Services because your partners behaviour will have a direct impact on yours. You need to protect yourself from a scenario where your partner's response times drops through the floor or they become unavailable. Remember this effect can be chained so they might be busy waiting on someone else!
So finally what is the solution? Well Fritz Onion has written a couple of really good articles on this both for ASP.NET 1.1 and ASP.NET 2.0 so there is no point in my repeating his excellent advice.
These articles can be found at:
Use Threads and Build Asynchronous Handlers in Your Server-Side Web Code (ASP.NET 1.1)
Async Pages in ASP.NET 2.0 - some results
The moral of this story; Be careful what code you write - I might just kill your web server!
The source code for my busy page is below.
public class WebForm1 : System.Web.UI.Page
{
Thread _t;
DateTime _start;
protected System.Web.UI.WebControls.Label Label1;
private void Page_Load(object sender, System.EventArgs e)
{
_start = DateTime.Now;
_t = new Thread(new ThreadStart(MyThread));
_t.Start();
}
private void MyThread()
{
string setting = ConfigurationSettings.AppSettings["ThreadWait"];
int wait = int.Parse(setting);
Thread.Sleep(wait);
}
protected override void OnPreRender(EventArgs e)
{
base.OnPreRender (e);
_t.Join();
Label1.Text = "Started - " + _start.ToLongTimeString()+"
";
Label1.Text += "Finished - " + DateTime.Now.ToLongTimeString();
}
#region Web Form Designer generated code
override protected void OnInit(EventArgs e)
{
//
// CODEGEN: This call is required by the ASP.NET Web Form Designer.
//
InitializeComponent();
base.OnInit(e);
}
///
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
///
private void InitializeComponent()
{
this.Load += new System.EventHandler(this.Page_Load);
}
#endregion
}
A friend of mine recently commented on the apparent stupidity of having a Milk Helpline listed on your regular bottle of semi-skimmed. To his surprise I told him this was a Maven Trap.
The obvious next question is "What is a Maven Trap?" To answer this properly I decided to buy him a copy of Malcolm Gladwell's excellent book The Tipping Point which is where I first came across the term.
To my surprise the chapter which talks about Maven Traps has been deleted from the current paperback edition of The Tipping Point so I contacted Malcolm Gladwell to find out why. He wasn't aware the chapter had been removed either but was kind enough to give me permission to re-publish it on my blog so here it is:
Finding the Mavens
Malcolm Gladwell, The Tipping Point
Whenever I look at an unopened bar of Ivory bath soap, I flip it over and burst out laughing. In the midst of all the production information, there is a line that says: “Questions? Comments? Call 1-800-395-9960.” Who on earth could ever have a question about Ivory soap? In fact, who on earth would ever have a question about Ivory soap so important that they felt compelled to call the company right away? The answer, of course, is that while most of us would never dial that number, a very small percentage of profoundly weird people may well feel compelled from time to time to call in with a question. These are people who feel passionate about soap. They are the soap Mavens, and if you are in the soap business you had better treat those soap Mavens well because they are the ones whom all their friends turn to for advice about soap.
The Ivory soap 800 number is what I call a Maven trap – a way of efficiently figuring out who the Mavens are in a particular world – and how to set Maven traps is one of the central problems facing the modern market-place. For the better part of a century, we defined influence in this country in the form of status. The most important influence in making up our minds, we were told, was the people who made the most money and who had the moist education and who lived in the choicest neighbourhoods. The virtual of this notion was that these kinds of people were easy to find: in face, and entire industry in the marketing world was created around the convenient delivery of long lists of people who had graduate degrees, made lots of money, and lived in nice neighbourhoods. But Connectors, Mavens, and Salesmen are a little different. They are distinguished not by worldly status and achievement, but by the particular standing they have among their friends. People look up to them not out of envy, but out of love, which is why these kinds of personalities have the power to break though the rising tide of isolation and immunity. But love is a very difficult thing to track. How on earth do you find these kinds of people?
This is a question that I’ve been asked again and again over the last year, and there is no easy answer. Connectors, I think, are the sorts of people who don’t need to be found. They make it their business to find you. But Mavens are a little harder, which is whey it is so important, I think, to come up with strategies for finding Mavens – Maven traps.
Consider the experiences of Lexus. In 1990, just after Lexus frst introduced its line of luxury cars in the United States, the company realized that it had two minor problems with its LS400 line that required a recall. This situation was, by any measure, an awkward one. Lexus had decide, from the beginning, to build its reputation around quality workmanship and reliability. And now, within little more than a year of the brand’s launch, the company was being forced to admit to problems with its flagship. So Lexus decided to make a special effort. Most recalls are handled by making an announcement to the press and mailing a notification letter to owners. Lexus, instead, call each owner individually on the telephone the day the recall was announced. When the owners picked up their cars at the dealership after the work was completed, each car had been washed and the tank filled with gas. If an owner lived more than a hundred miles from a dealership, the dealer sent a mechanic to his or her home. In one instance, a technician flew from Los Angeles to Anchorage to make the necessary repairs.
Was it necessary to go to such lengths? You could argue that Lexus overreacted. The problems with the car were relatively minor. And the number of cars involved in the recall – so soon after Lexus had entered the marketplace- was small. Lexus would seem to have had many opportunities to correct the damage. The key fact, though, was not the number of people affected by the recall but the kind of people affected by the recall. Who, after all, are the people willing to take a chance and buy a brand-new luxury model? Car Mavens. There may have been only a few thousand Lexus owners at that point, but they were car experts, people whose friends ask them for advice about cars. Lexus realized that it had a captive audience of Mavens and that if they went the extra mile they could kick-start a word-of-mouth epidemic about the quality of their customer service – and that’s just what happened. The company emerged form what could have been a disaster with a reputation for customer service that continues to this day. One automotive publication later called it “the perfect recall.”
This is the perfect Maven trap – using the recognition that sometimes a specific time or place or situation happens to bring together a perfect Maven audience.
I would also strongly recommend Malcolm's new book Blink.
We are next running our very popular "New Technology Seminar" on Wednesday 27th April.
http://www.sentient.co.uk/newtechnologyseminar.aspx
Microsoft has kindly sponsered this event which means we can offer FREE entry for this time only.
In the seminar we will be showing you how you can use the following technologies to improve your business effectiveness:
Blogging - weblogs, blogs, rss, ezine replacement, subscription revenue
Bluetooth - bluejacking, tracking, prescence
Google - SEO, AdWords, AdSense
Skype - VoIP, SkypeOut, SkypeAPI
Firefox - What makes this new browser so special?
Instant Messenger - MSN Messenger, Video conferencing
Wireless - WiFi, Hotspots, Roaming.
Mobile Devices - SmartPhone, Tablet PC, Pocket PC (PDA)
Location Data - MapPoint, GPS, GIS Mapping
Website Security - Avoiding SQL Injection, Cross-site Scripting
Viruses and Spyware - Prevention is better than cure
I am also constantly looking for new technology which can help us be more effective. Please add your recommendations to this blog.
Thanks
Jonathan
VBUG (Manchester) in association with INETA have asked me to talk about System.Threading at their meeting on Wednesday 9th March.
For more information please follow this link:
http://www.vbug.net/events/default.asp?region=Manchester (too be listed soon)
Hope to see you there.
Jonathan
PS. When I originally posted this the topic was SharePoint so if you are seeing cached/aggregated version of this that explains the disparity.
VBUG (Essex) in association with INETA have asked me to talk about System.Threading at their meeting on Monday 4th April.
For more information please follow this link:
http://www.vbug.net/events/default.asp
Hope to see you there.
Jonathan
VBUG (London) in association with INETA have asked me to talk about SharePoint at their meeting on Wednesday 15th March.
For more information please follow this link:
http://www.vbug.net/events/default.asp?region=London
Hope to see you there.
Jonathan
During my System.Threading talk last night one of the questions from the audience asked what the IsBackground property on the Thread classes was used for.
The intellisense for this property says "Gets or Sets a value indicating whether or not the tread is a background thread." which to be honest I think we could have guessed! What this description lacks is any information about why you would want to set it.
It's always embarrassing when you can't immediately answer a question from the audience but in this case I was stumped so I promised to investigate the answer and here it is.
The IsBackground property allows you to tell the runtime if the thread is a foreground (UI) thread or a background thread. By default all threads are created as foreground threads unless you change this property.
So why do we care?
Well, the .NET runtime does something special when the last foreground thread terminates - it aborts all the background threads and terminates the application. (We know Thread.Abort is bad however if the application is being shutdown anyway that badness has a very limited duration.)
This can be nicely illustrated by creating a WinForms application which launches a background thread which runs forever. By default when you run your application it will run forever unless you explicitly abort the background thread or the application. This can be seen by running your simple application, closing the Form1 window and noticing the application is still running.
If however you set IsBackground to true after creating your background thread:
Thread t = new Thread(new ThreadStart(BackgroundThread));
t.IsBackground = true;
t.Start();
You will notice that when you close the only window (Form1) the application will terminate.
I will certainly be updating our System.Threading presentation to explain this behaviour more clearly in the future. A great question and something we should all be doing.
VBUG (Coventry) in association with INETA have asked me to talk about System.Threading at their meeting on Tuesday 15th February.
For more information please follow this link:
http://www.vbug.net/events/default.asp?region=Leicester
Hope to see you there.
Jonathan
VBUG (Horsham) in association with INETA have asked me to talk about SharePoint at their meeting on Thursday 10th February.
For more information please follow this link:
http://www.vbug.net/events/default.asp?region=Portsmouth
Hope to see you there.
Jonathan