bradyep.com

A Vanity Website

Simple .NET Threading

The Problem

I have to admit that as a web and business applications developer, I don't run into a tremendous amount of situations where threading is necessary. I've used it a few times in testing situations, but I didn't find it absolutely necessary until I started my latest personal project, newsglance.net.

The issue was that when a user wants to see their feeds, my code checks to see if it has some recently cached items it can serve up, but if it cannot find those, then it needs to grab some fresh content from the web. Since a user can have many feeds on a page, you run into a performance bottleneck where the code is constantly waiting to get RSS feeds back from various servers. Sounds like a pretty good case for threading!

The Solution

First I iterate all the feeds the user has set up:

                if (matchedInCache.Count < 1)
                {
                    ThreadPool.QueueUserWorkItem(new WaitCallback(PullWebFeed), nf);
                    // PullWebFeed(ref editedNewsFeed);
                }

If we can't find it in the cache, we create a "UserWorkItem" can has its own method call - in this case, the method to call for each work item is "PullWebFeed":

        public static void PullWebFeed(Object stateInfo)
        {
            NewsFeed nf = (NewsFeed)stateInfo;

            try
            {
                // If not, try to pull the NewsFeed from the web, using its FeedSource
                XmlReader localReader = XmlReader.Create(nf.FeedSourceURL);
                // Try to create a SyndicationFeed from an XmlReader
                SyndicationFeed feed = new SyndicationFeed();
                feed = SyndicationFeed.Load(localReader);
    }
    newsFeedsCompletedProcessing++;
}

This method takes the identifying feed information (nf) and grabs the relevant RSS feed for it on the internet. Since we are iterating through all News Feeds, we just keep creating as many new worker items as we can until we run out of jobs. But how do we know when we are done with all our work since we are waiting on a callback? Here's what I did:

            while (newsFeedsCompletedProcessing < newsFeeds.Count)
            {
                // Do nothing since we need to wait for our threads to complete

            }

Closing Thoughts

Yep, just an empty statement that keeps getting executed until we know we've gotten all of our feeds. This didn't seem like the most elegant possible solution to the problem, but it does work.

So was this additional code worth it? Well for the page with all of the feeds I went from an average 6-7 second load time to a 2-3 second load time, so moving to threads more than doubled my performance! This is obviously dependent on how many cores you have to work with: more cores means the work can be further split up and run in parallel.

I should mention that the 'ThreadPool' class is viewed as the "old way" of working with threads in .Net. It still works and is not deprecated, but a supposedly simpler and more powerful method of threading was introduced in .Net 4.5: the 'wait' and 'async' operators. Next time I run into another threading issue I'll have to take a look at them, and maybe make another blog post as well!