-
Operating system must go in to kernel mode.
-
Other threads must notify the new thread is created.
-
Operating system must leave the kernel mode. Etc...
If you want to know about the kernel mode refer to http://www.codinghorror.com/blog/archives/001029.html
From the developers point of view
-
Multithreading applications are hard to debug.
-
And makes the application more complex.
Somehow it's up to developer to take challenge over the choice
Then why should we use threads?
So if this is such a costly process then why should we are using the threads...
Answer is within last couple of years processors had a rapid development especially on its speed. Nowadays a processor in the market is with a speed around 3GHz - 4GHz.when processor comes up to this level processor vendors such as Intel, AMD used to notified that processor can't be speeds up more and more with the environment they should use. Then they used to think about parallel processing, here's the point Hyper-threading technology comes in to action. Later they improved it to Dual Core then in to Core 2 Duo... I'm not going describe all those CPU architectures by here, and it's not what I except by this article as well. So my point is to "why should we use threads in our applications" and the answer is to use the maximum performance and of the above processors (advantage of parallel processing) we have to use the threads with our C# applications.
Using threads with C# application
There are several ways that we can use threads .net framework applications.
First I'll describe you how to use a dedicated thread within our application and later I'll describe you about using Thread pool and thread synchronization techniques as well. And I hope you have some knowledge of working with delegates at least why we are using delegates in C#. You can learn basics about delegates from here
http://msdn.microsoft.com/en-us/library/ms173171(VS.80).aspx
Example: Using dedicated threads
C# code
class Program
{
static void Main(string[] args)
{
// create thread start delegate instance - contains the method to execute by the thread
ThreadStart ts = new ThreadStart(run);
// create new thread
Thread thrd = new Thread(ts);
// start thread
thrd.Start();
// makes the main thread sleep - let sub thread to run
Thread.Sleep(1000);
for (int t = 10; t > 0; t--)
{
Console.WriteLine("Main Thread value is :" + t);
Thread.Sleep(1000);
}
Console.WriteLine("Good Bye!!!I'm main Thread");
Console.ReadLine();
}
// this method executed by a separate thread
static void run()
{
for (int i = 0; i < 10; i++)
{
Console.WriteLine("Sub Thread value is : " + i);
Thread.Sleep(1000);
}
Console.WriteLine("Good Bye!!!I'm Sub Thread");
}
}
VB.net code
Module Module1
Sub Main()
'create thread start delegate instance - contains the method to execute by the thread
Dim ts As ThreadStart = New ThreadStart(AddressOf run)
' create new thread
Dim t As Thread
t = New Thread(ts)
' start thread
t.Start()
' makes the main thread sleep - let sub thread to run
Thread.Sleep(1000)
For i As Integer = 10 To 0 Step -1
Console.WriteLine("Main thread value is" + i.ToString())
Thread.Sleep(1000)
Next i
Console.WriteLine("Good Bye!!!I'm main Thread")
Console.ReadKey()
End Sub
' this method executed by a separate thread
Sub run()
For i As Integer = 0 To 10
Console.WriteLine("Sub thread value is" + i.ToString())
Thread.Sleep(1000)
Next i
Console.WriteLine("Good Bye!!!I'm Sub Thread")
End Sub
End Module
In the above code I have used a separate thread to execute my run method. When code executes you can see the output
Sub thread increases the value within its run method and the main thread decreases its value one after the other.
Here's the part we have created a new thread and assigned job to done.
// create thread start delegate instance - contains the method to execute by the thread
ThreadStart ts = new ThreadStart(run);
// create new thread
Thread thrd = new Thread(ts);
// start thread
thrd.Start();
In here the thread start delegate is optional and we can directly create the thread like this as well
// create new thread
Thread thrd = new Thread(run);
// start thread
thrd.Start();
Note: This is C# language shortcut and does not available with VB.net.
Make the thread a background thread
This thread remains runing even the main thread finishes it's job, to finalize all the threads when main thread dies you have to set the IsBackground property to true.
// create new thread with ParameterizedThreadStart delegate instance
Thread thrd = new Thread(run);
// make the thread background
thrd.IsBackground = true;
// start thread with passing the parameters need
thrd.Start();
Passing parameters to the threads
If you want to pass any parameters to the method which is used to execute by the new thread then you can use the ParamerizedThreadStart delegate instead of the ThreadStart delegate.
Example: Using ParameterizedThreadStart to invoke methods with parameters
ParameterizedThreadStart which we used to execute our method by a separate thread looks like this
public delegate void ParameterizedThreadStart(object obj);
So we have to change our run method like this (matches with the ParameterizedThreadStart)
/* this method executed by a separate thread
* this sholud be match with the ParameterizedThreadStart
* (parameters must be passed as an object)
*/
static void run(object args)
{
// cast our parameter
int j = (int)args;
for (int i = 0; i < j; i++)
{
Console.WriteLine("Sub Thread value is : " + i);
Thread.Sleep(1000);
}
Console.WriteLine("Good Bye!!!I'm Sub Thread");
}
Executing part is like this (please read the comments)
// create new thread with ParameterizedThreadStart delegate instance
Thread thrd = new Thread(new ParameterizedThreadStart(run));
// start thread with passing the parameters need
thrd.Start(10);
Assigning Thread pool class to get the job done
By using the threadpool class we can assign our work to done by a separate thread easily and this is the way recommended using whenever possible.
Example: Using Threadpool class
// assign thread pool thread to do the job
ThreadPool.QueueUserWorkItem(run);
If you want to pass any parameters to the method executing by the thread you can pass them as a second argument.like this for our run method with object parameter.
// assign thread pool thread to do the job
ThreadPool.QueueUserWorkItem(run,10);
Complete code
class Program
{
static void Main(string[] args)
{
// assign thread pool thread to do the job
ThreadPool.QueueUserWorkItem(run,10);
// makes the main thread sleep - let sub thread to run
Thread.Sleep(1000);
for (int t = 10; t > 0; t--)
{
Console.WriteLine("Main Thread value is :" + t);
Thread.Sleep(1000);
}
Console.WriteLine("Good Bye!!!I'm main Thread");
Console.ReadLine();
}
/* this method executed by a separate thread
* this sholud be match with the WaitCallback
* (parameters must be passed as an object)
*/
static void run(object args)
{
// cast our parameter
int j = (int)args;
for (int i = 0; i < j; i++)
{
Console.WriteLine("Sub Thread value is : " + i);
Thread.Sleep(1000);
}
Console.WriteLine("Good Bye!!!I'm Sub Thread");
}
}
Periodic operations from threads
If you want to perform any method call in a perodic order then you can use the Timer class.
Note : There are three timer classes availbale with .net framework class library one is in System namespace next is in System.Windows.Forms namespace and the last is in System.Threading namespace all of them are providing similar functinalties so please don't confuse them together,I'm talking here is about the System.Threading.Timer class
Example: Using Timer class
class Program
{
static void Main(string[] args)
{
// assign thread timer to do the job
System.Threading.Timer thrdTimer = new Timer(run, 10, 0, 1000);
// makes the main thread sleep - let sub thread to run
Thread.Sleep(1000);
Console.WriteLine("Good Bye!!!I'm main Thread");
Console.ReadLine();
}