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:

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.)

Using the thread pool instead

One alternative to starting the thread using a ThreadStart delegate
is to use the thread pool, either using ThreadPool.QueueUserWorkItem
or by calling a delegate asynchronously. Both of these are covered later on in
a more detailed discussion of the thread pool, which
also contains examples. Note that calling a delegate asynchronously allows you
to specify multiple parameters, and those parameters are strongly typed.

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):

(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:

.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...]
staticvoid FetchUrl(object url)
{
// use url here, probably casting it to a known type before use
}