Proxy > Gmail Facebook Yahoo!

Utilize ThreadPool in WebService



The following code snippet will show you how to create a multi-threaded web service. For the sake of the example, let us assume that we are creating Video Search Service, which will search different sites such as YouTube, MetaCafe, and DailyMotion for a given keyword and returns a composite result. Since this search can be done independently, we can surly invoke separate threads for each search. Let us see how we can utilize the built-in ThreadPool to create a multithread web service.
    1 using System;
    2 using System.Threading;
    3 using System.Collections;
    4 using System.Collections.Generic;
    5 using System.Web;
    6 using System.Web.Services;
    7 
    8 
    9 public class Video
   10 {
   11     public string Title;
   12     public string Author;
   13     public string Description;
   14     public string Url;
   15     public string OriginalUrl;
   16     public string Thumbnail;
   17     public string Source;
   18 }
   19 
   20 [WebService(Namespace = "http://tempuri.org/")]
   21 [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
   22 public class VideoSearchService : WebService
   23 {
   24     public VideoSearchService()
   25     {
   26     }
   27 
   28     [WebMethod()]
   29     public List<Video> Search(string keyword)
   30     {
   36         List<Video> result = new List<Video>();
   37         List<ManualResetEvent> locks = locks = new List<ManualResetEvent>();
   38         ManualResetEvent evt;
   39 
   40         evt = new ManualResetEvent(false);
   41         locks.Add(evt);
   42         ThreadPool.QueueUserWorkItem(new WaitCallback(SearchDailyMotion), (object)(new object[] { keyword, result, evt}));
   43 
   44         evt = new ManualResetEvent(false);
   45         locks.Add(evt);
   46         ThreadPool.QueueUserWorkItem(new WaitCallback(SearchMetaCafe), (object)(new object[] { keyword, result, evt }));
   47 
   48         evt = new ManualResetEvent(false);
   49         locks.Add(evt);
   50         ThreadPool.QueueUserWorkItem(new WaitCallback(SearchYouTube), (object)(new object[] { keyword, result, evt }));
   51 
   52         //This will ensure that all the threads completes its search
   53         EventWaitHandle.WaitAll(locks.ToArray());
   54 
   55         return result;
   56     }
   57 
   58     private void SearchDailyMotion(object state)
   59     {
   60         object[] triplet = (object[])state;
   61 
   62         string keyword = (string)triplet[0];
   63         List<Video> result = (List<Video>)triplet[1];
   64         ManualResetEvent evt = (ManualResetEvent)triplet[2];
   65 
   66 
   67         //DailyMotion will searhed over here
   68 
   69         evt.Set(); // Search is complete, so notify the parent thread
   70     }
   71 
   72     private void SearchMetaCafe(object state)
   73     {
   74         object[] triplet = (object[])state;
   75         string keyword = (string)triplet[0];
   76         List<Video> result = (List<Video>)triplet[1];
   77         ManualResetEvent evt = (ManualResetEvent)triplet[2];
   78 
   79         //MetaCafe will be searched over here
   80 
   81         evt.Set(); // Search is complete, so notify the parent thread
   82     }
   83 
   84     private void SearchYouTube(object state)
   85     {
   86         object[] triplet = (object[])state;
   87         string keyword = (string)triplet[0];
   88         List<Video> result = (List<Video>)triplet[1];
   89         ManualResetEvent evt = (ManualResetEvent)triplet[2];
   90 
   91         // YouTube will be searched over here
   92 
   93         evt.Set(); // Search is complete, so notify the parent thread
   94     }
   95 }

The whole thing has been done in four steps:
 Step 1:
 We created few variables:
  • A Generic List of Video which holds the search result
  • A Generic List of Locks which is actually ManualResetEvent class
  • A ManualResetEvent class to instantiate for different search.
Step 2:
Starting each Search, this steps are repeated for the 3 different search:
  • We created an Instance ManualResetEvent class and Adds it in the locks list. ManualResetEvent is special class, which allows us to communicate with different threads by signaling.
  • Next, we queue a Task in a ThreadPool passing the Keyword, The Result list where the search result will be appended by the child thread and ManualResetEvent. The ThreadPool class method QueueUserWorkItem only takes a WaitCallback delegate which only accepts a single argument of object type and that's way we creating array on the fly and putting these items in that array. When a task is queued in the ThreadPool, the ThreadPool picks a free thread from its pool fires the thread to run the assigned method in that thread.
Step 3:
Inside the Child Thread :
  • Cast back the argument to proper types.
  • Search the Site. I have commnted this to make the code shorter
  • Then call the set() method of the ManualResetEvent. By calling this method, we are sending signal to the parent thread that the thread has done its job.
Step 4:
The parent thread:
  • The Parent threads call the EventWaitHandle.WaitAll(). This ensures that the parent thread will wait until all the child threads complete its job.
And We are Done!
Few Notes:
  • It is not possible to access the HttpContext.Current from the Child Thread method which means it also not possible to access the Request, Response, Cache, Session etc. If you need any of these objects in the child thread method then you also have to pass it in the WaitCallback like we did in the above.
  • Never Creates a New Thread alternatively use the Built in ThreadPool class.
  • Queuing a Task does not ensure that it will started be instantly, it completely depends upon the current usage of the ThreadPool, if the ThreadPool is already saturated with previous tasks then there might be a chance that your application will perform poorly even comparing with the Single threaded approach.


Responses

0 Respones to "Utilize ThreadPool in WebService"


Send mail to your Friends.  

Expert Feed

 
Return to top of page Copyright © 2011 | My Code Logic Designed by Suneel Kumar