Passing parameters to Threads

Often when you start a thread, you want to give it some parameters - usually some data it has to process, a queue to wait on, etc. The ThreadStart delegate doesn't take any parameters, so the information has to be stored somewhere else if you are going to create a new thread yourself. Typically, this means creating a new instance of a class, and using that instance to store the information. Often the class itself can contain the delegate used for starting the thread. For example, we might have a program which needs to fetch the contents of various URLs, and wants to do it in the background. You could write code like this:


public class UrlFetcher
{
string url ;

public UrlFetcher (string url)
{
this.url = url;
}

public void Fetch()
{
// use url here
}
}

[... in a different class ...]

UrlFetcher fetcher = new UrlFetcher (myUrl);
new Thread (new ThreadStart (fetcher.Fetch)).Start();



In some cases, you actually just wish to call a method in some class (possibly the currently executing class) with a specific parameter. In that case, you may wish to use a nested class whose purpose is just to make this call - the state is stored in the class, and the delegate used to start the thread just calls the "real" method with the appropriate parameter. (Note that the object on which to call the method in the first place will also be required as state unless the method is static.)

.NET 2.0 solution 1: anonymous methods (with and without the thread pool)

One of the enhancements to C# in version 2.0 is anonymous methods. These allow you to specify blocks of code as methods within other methods, and use those methods as delegates. You can access variables (including local variables and parameters of the "outside" method) within the anonymous method. For example, using an anonymous method to fetch a URL using a normal ThreadStart delegate (and using inference of delegate type too):



ThreadStart starter = delegate { Fetch (myUrl); };
new Thread(starter).Start();

(This could have all been expressed within a single step, creating both the thread and the delegate in the same line of code, but I believe the above is more readable.) Here's similar code to use a WaitCallback and queue the job in ThreadPool:




WaitCallback callback = delegate (object state) { Fetch ((string)state); };
ThreadPool.QueueUserWorkItem (callback, myUrl);

.NET 2.0 solution 2: ParameterizedThreadStart
In .NET 2.0, there is a new delegate, ParameterizedThreadStart, which takes a parameter of type object. You can create a thread using an instance of this delegate instead of just ThreadStart, and a new overload to Thread.Start allows you to specify the value to be passed to the new thread. This is simple, but only accepts a single parameter and isn't type-safe (just like the options when using thread pool threads). The earlier code could then be rewritten as:




[In some method or other]
Thread t = new Thread (new ParameterizedThreadStart(FetchUrl));
t.Start (myUrl);
[And the actual method...]
static void FetchUrl(object url)
{
// use url here, probably casting it to a known type before use
}


Refrence : http://www.yoda.arachsys.com

Comments

Popular posts from this blog

Use configSource attribute to manage Web.Config sections in ASP.Net 2.0

DevOps - Key Concepts - Roles & Responsibilities - Tools & Technologies

Trouble In the House of Google