April 19

Queueing with the Smart Thread Pool – Update

Posted by Dave
Filed under ASP.Net | No Comments


Introduction

After posting this on the Smart Thread Pool (STP) I have created a small example on its usage in an ASP.Net MVC project. Using a wrapper class that implements the singleton pattern I now have a way to use the STP to share a queue across all of the sites users. Ideal for submitting jobs to a set number of consumer processes for fast processing.

STP Usage

Just a quick mention of the suggested usage for the STP. This is what Ami Bar (STP creator) suggests.

The Smart Thread Pool is good when your work items don’t do too much, but wait for events, IOs, sockets, etc. This means that the work items don’t use CPU, but run for a long time. It is also good when you don’t need to keep alive too many threads in the air all the time. If your work items do a short time work, then use the .NET ThreadPool. If you have a constant heavy load of work, then use Toub’s thread pool and define the maximum number of threads accordingly.

Wrapper Class

This class gets instanced in the global.asax and then wheneaver it is needed it is called with a call to:

 Singleton s = Singleton.Instance;

The singleton pattern ensures that only one instance of the wrapper class exists and is shared at an application level. Jobs are then added to the queue using the AddJob method, which returns the index in the handles property where the IWorkItResult is located.

 int job1Index = s.AddJob(inttime);

Singleton Class

  public sealed class Singleton
    {
        static readonly Singleton instance = new Singleton();
        private static Queue Queues;
        private static SmartThreadPool pool;
        private static ArrayList handles;
        public ArrayList Handles
        {
            get { return handles; }
            set { handles = value; }
        }
        public int ActiveThreads
        {
            get { return pool.ActiveThreads; }
        }
        public int InUseThreads
        {
            get { return pool.InUseThreads; }
        }
        public int AddJob(object job)
        {
            IWorkItemResult wir = pool.QueueWorkItem(new WorkItemCallback(DoRealWork), job);
            handles.Add(wir);
            return handles.IndexOf(wir);
        }
        private object DoRealWork(object job)
        {
            object res = "Not Done";
            int time = (int)job;
            //do the work
            Thread.Sleep(time * 1000);
            res = "done";
            return res;
        }
        public static Singleton Instance
        {
            get
            {
                return instance;
            }
        }
        // Explicit static constructor to tell C# compiler
        // not to mark type as beforefieldinit
        static Singleton()
        {
            handles = new ArrayList();
            STPStartInfo sinfo = new STPStartInfo();
            sinfo.MaxWorkerThreads = 10;
            sinfo.MinWorkerThreads = 0;
            sinfo.UseCallerHttpContext = true;
            pool = new SmartThreadPool(sinfo);
        }
        Singleton()
        {
        }
    }

Usage

In this example the singleton takes in an int as its input and the Singleton DoRealWork method halts the thread for that many seconds. This is just to show the functionality of the threads being added.

 [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult Index(string time)
        {
            Singleton s = Singleton.Instance;
            int inttime;
            ViewData["handles"] = s.Handles;
            if (!int.TryParse(time, out inttime))
                ViewData.ModelState.AddModelError("time", "Please enter a number!");
            if (ViewData.ModelState.IsValid)
            {
                int job1Index = s.AddJob(inttime);
                string message = "There are " + s.ActiveThreads + " active threads and " + s.InUseThreads + " in use threads";
                ViewData["Message"] = message;
            }
            if (Request.IsAjaxRequest())
            {
                return PartialView("QueueList");
            }
            else
            {
                return View();
            }
        }

Conclution

The STP in this example is shared to all users of the site and any user can add to the queue and see what the queue contains. I hope to take this and implement it in a project that I am curently working on where the usese submit work to a system and this gets processed and the result returned. More on that in future blog posts.

As always any comments on this article are welcomed and happy coding.

Popularity: 2% [?]

Share this post
  • Twitter
  • Digg
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • Diigo
  • LinkedIn
  • Reddit
  • Technorati

Other Stuff You Might Like

This entry was posted on Sunday, April 19th, 2009 at 13:00 and is filed under ASP.Net. You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.

Leave a Reply