Background threads in ASP.net applications (Part 1 – the concept application)
When debugging memory dumps from customers, I have come to see, quite often, a pattern that you should not use in your application if you don't want to run into trouble. This pattern can be resumed in a simple rule: thou shall not create thy own threads in thy application! To show you what I mean, through a series of three blog articles I will create a simple application and show you what happens when we transgress this rule.
Let's build a simple stock quote lookup application. I am basing my sample on a sample I found earlier and bookmarked with www.linqto.me under this url: https://linqto.me/StockAPI . Since the API in question is now defunct, and I wanted to provide a working app, I have performed some major changes, including using the Yahoo API instead of the Google one. You can download the completed solution from my OneDrive here:
Background Threading Sample Applications
When you start the solution, you should see a page that allows you to input a stock symbol and get a quote. Here is the page loaded in Internet Explorer and showing the price for the MSFT stock symbol:
So how does this work? The page has a textbox called txtSymbol and a button which, when pressed, will submit the page and run some code behind to lookup the symbol in the Yahoo API. The code behind has a click event associated to the button, which looks like this:
protected void cmdSubmit_Click(object sender, EventArgs e)
{
//check if there is a symbol in the textbox
if (!String.IsNullOrWhiteSpace(txtSymbol.Text.Trim()))
{
//get a quote from Yahoo:
FetchQuote(txtSymbol.Text.Trim());
//show the panel and set the labels
pnlResults.Visible = true;
lblCompany.Text = company;
lblPrice.Text = price.ToString();
lblSymbol.Text = symbolName;
lblVolume.Text = volume.ToString();
}
}
If the textbox is not empty (I am not doing fancy error checking to keep this simple), the code will call a method called FetchQuote(System.String) to which it will pass the value of the textbox. Here is the code for this second method:
private void FetchQuote(string symbol)
{
string url = "https://finance.yahoo.com/webservice/v1/symbols/" + Server.UrlEncode(symbol) + "/quote";
//load the xml document
XDocument doc = XDocument.Load(url);
//extract the data
company = GetData(doc, "name");
price = Convert.ToDouble(GetData(doc, "price"));
symbolName = GetData(doc, "symbol");
volume = Convert.ToInt32(GetData(doc, "volume"));
}
The method will compose the Yahoo Stock API url with the stock symbol we want to look up. It will down the XML document containing the quote data from Yahoo. Such a document will look something like this for the MSFT (Microsoft) stock symbol
<list version="1.0">
<meta>
<type>resource-list</type>
</meta>
<resources start="0" count="1">
<resource classname="Quote">
<field name="name">Microsoft Corporation</field>
<field name="price">47.980000</field>
<field name="symbol">MSFT</field>
<field name="ts">1416603605</field>
<field name="type">equity</field>
<field name="utctime">2014-11-21T21:00:05+0000</field>
<field name="volume">42887245</field>
</resource>
</resources>
</list>
Once the document is loaded into an XDocument object, we will parse the object to extract the data we need to show on the page. This is done by repeated calls to a method called GetData(System.Xml.LINQ.XDocument, System.String). Here is the code:
private string GetData(XDocument doc, string name)
{
//get the requested attribute value from the XDocument
return doc.Root.Element("resources").Element("resource").Elements().Where(n => n.FirstAttribute.Value == name).First().Value;
}
I will not go into the details of this implementation, suffice to say that it will attempt to get a hold of an XML element that has an attribute called name with the 'value' indicated by the String parameter passed in. It will just return the value of the XML element which is the quote data we are interested in.
Back to the FetchQuote method, which will load the retrieved data into local page variables. Following this, it will return control to the caller, the Click event handler of the button. This will display a Panel control and transfer the values of the page level variables to label controls on the page to display the data.
In the next installment, I will be modifying the application to load the data for stock symbols in the background, periodically, so that we do not lose time to load the data from Yahoo every time someone asks for a quote from the application. This will be done via background threads, the kind of pattern you should not be using. The implementation of this concept is detiled in the second blog post.
By Paul Cociuba
https://linqto.me/about/pcociuba
Comments
Anonymous
November 24, 2014
Useful!! thank you!Anonymous
November 24, 2014
Very useful, simple and informative, I am waiting for your background loading implementation.Anonymous
November 25, 2014
"thou shall not create thy own threads in thy application" Few rules are "always" rules. Will be interesting to see what your point is.Anonymous
November 25, 2014
Hello everyone, thank you for the great feedback, the second part is available here: blogs.msdn.com/.../background-threads-in-asp-net-applications-part-2-thread-implementation.aspx