Blue Theme Orange Theme Green Theme Red Theme
 
Team Foundation Server Hosting
Home | Forums | Videos | Advertise | Certifications | Downloads | Blogs | Interviews | Jobs | Beginners | Training
 | Consulting  
Submit an Article Submit a Blog 
 Jump to
Skip Navigation Links
TechnologyExpand Technology
WebsiteExpand Website
Discover the top 5 tips for understanding .NET Interop
Search :       Advanced Search »
Home » Threading in C# » Multithreading Part 2: Understanding the System.Threading.Thread Class

Multithreading Part 2: Understanding the System.Threading.Thread Class

In this article we will study the .NET threading API, how to create threads in C#, start and stop them, define their priorities and states.

Page Views : 67803
Downloads : 0
Rating :
 Rate it
Level : Beginner
   Print Read/Post comments Post a comment  Similar Articles  
   Email to a friend  Bookmark  Author's other articles  
 
DevExpress Free UI Controls
Become a Sponsor
DevExpress Free UI Controls
Become a Sponsor
 Tag Cloud
 Latest Jobs
More ... 
 Latest Interview Questions
More ... 

In this article we will study the .NET threading API, how to create threads in C#, start and stop them, define their priorities and states.

Applications written on the .NET platform are naturally threaded. Let us study threading with respect to C# as the programming language. The runtime environment starts execution of the program with the Main () method in one thread. We all know that there is an automatic garbage collection happening in the background. This takes place in another thread. All of this happens so naturally that it goes unnoticed. There are situations when we need to add threads to our application. We have already seen the numerous situations in  Multithreading -- part1 of the article, where we might feel the need to add new threads. A few common requirements being when you need to handle user-input, or do a lengthy calculation etc. To put it more generally, any operation that is time-critical, or needs constant attention or is time-consuming should be placed in a thread of its own.

The classes and interfaces in the System.Threading namespace provide the multithreading support in the .NET platform. This namespace consists of a number of classes. We will be discussing the Thread class of this namespace.

System.Threading.Thread is the main class for creating threads and controlling them. The Thread class has a number of methods. A few interesting methods are shown below:

  • Start(): starts the execution of the thread.
  • Suspend(): suspends the thread, if the thread is already suspended, nothing happens.
  • Resume() : resumes a thread that has been suspended.
  • Interrupt(): interrupts a thread that is in the wait, sleep or join stage.
  • Join(): blocks a calling thread until the thread terminates.
  • Sleep(int x) : suspends the thread for specified amount of time (in milliseconds).
  • Abort(): Begins the process of terminating the thread. Once the thread terminates, it cannot be restarted by calling the function Start() again.

You can pause/block a thread by calling Thread.Sleep or Thread.Suspend or Thread.Join. Calling the method Sleep() or Suspend() on a thread means, the thread does not get any processor time. There is a difference between these two ways of pausing a thread. Thread.Sleep causes a thread to stop immediately but the common language runtime waits until the thread has reached some safe point before calling the Suspend() method on the thread. One thread cannot call Sleep() on another thread but one thread can call Suspend() on the other thread and it causes the other thread to pause. Calling Resume() on the suspended thread breaks the thread out of the suspended state and allows it to continue execution. A single call to Resume() is sufficient to activate a thread regardless of the number of times Suspend() was called to block it. A thread that has already been terminated or has not yet started functioning cannot be suspended. Thread.Sleep(int.Infinite) causes a thread to sleep indefinitely. The thread can only wake up when it is interrupted by another thread that calls Thread.Interrupt or is aborted by Thread.Abort. You can use Thread.Interrupt to break a thread out of its blocking state but it throws a ThreadInterupptedException. You can either catch the exception, do whatever you want to do with the thread, or ignore the exception and let the run-time stop the thread. For managed wait, Thread.Interrupt and Thread.Abort both wake up the thread immediately.

It may be desirable at times to terminate a thread from some other thread. In such situations you use the Thread.Abort method to stop a thread permanently and using this function throws a ThreadAbortException. The terminating thread can catch the exception but it is difficult to suppress it. The only way that it can be suppressed is by calling Thread.ResetAbort method but it can only be called if this thread had been the one that had provoked the exception. Since, Thread.Abort is normally called by some thread A on some other thread B, B therefore, cannot invoke the method Thread.ResetAbort to suppress it from terminating. The Thread.Abort method lets the system quietly stop the thread without informing the user. Once aborted, a thread cannot be restarted. As this method does not say that the thread will abort immediately, hence to be sure that the thread has terminated, you can call Thread.Join to wait on the thread. Join is a blocking call that does not return until the thread has actually stopped executing. But remember, a thread may call Thread.Interrupt to interrupt another thread that is waiting on a call to Thread.Join.

As far as possible, you should avoid using Suspend() to block a thread as it could lead to serious problems like deadlocks. Imagine, what would happen if we suspend a thread that holds a resource that another thread would need. Rather, you should give different priorities to the thread based on their importance. You should, as far as possible, use Thread.Priority rather than Thread.Suspend.

This class also has a number of interesting properties as shown below:

  • IsAlive: (if true, signifies that thread has been started and has not yet been terminated or aborted)
  • Name (gets/sets the name of the thread)
  • Priority (gets/sets the scheduling priority of a thread)
  • ThreadState (gets a value containing the state of the current thread).

The example, shown below, is a very simple one that discusses how to apply these thread properties. More useful examples would follow in the coming series.

To create a thread, we need to instantiate the Thread class, passing a ThreadStart delegate (System.Threading.ThreadStart) in its constructor. This delegate contains the method where the thread will begin execution, when started. The Start() method of the Thread class then starts the execution of a new thread. Let us understand the concept with a small example.

using System;
using System.Threading ;
namespace LearnThreads
{
class Thread_App
{
public static void First_Thread()
{
Console.WriteLine("First thread created");
Thread current_thread = Thread.CurrentThread;
string thread_details = "Thread Name: " + current_thread.Name +
"\r\nThread State: " + current_thread.ThreadState.ToString()+
"\r\n Thread Priority level:"+current_thread.Priority.ToString();
Console.WriteLine("The details of the thread are :"+ thread_details);
Console.WriteLine ("first thread terminated");
}
public static void Main()
{
ThreadStart thr_start_func =
new ThreadStart (First_Thread);
Console.WriteLine ("Creating the first thread ");
Thread fThread =
new Thread (thr_start_func);
fThread.Name = "first_thread";
fThread.Start ();
//starting the thread
}
}
}

In this example, we are creating a new thread called fThread, which when started executes the function called First_Thread(). Note the use of the delegate called ThreadStart that contains the address of the function that needs to be executed when the thread's Start() is called.

Thread States

System.Threading.Thread.ThreadState property defines the state in which a thread is during the execution of the thread. Once created, a thread is always in at least one of the states till it is terminated. When a thread is created it is in Unstarted state. Start() method of the Thread class changes this state to a Running state for the thread. The thread continues to be in this state till it goes into a sleep or is suspended or is aborted or the thread terminates naturally. When the thread is suspended is goes into the Suspended state till another thread resumes it, when it is back again to the Running state. On being aborted or terminated, the thread is stopped and the ThreadState is Stopped. Once stopped, a thread can never leave the Stopped state just as once started a thread can never return to the Unstarted state. There is another state called Background state, which indicates whether a thread is running in the foreground or background.  A thread can be in multiple states at a given point in time. Say, a thread is blocked on a call to Sleep and another thread calls Abort on the blocked thread. What happens?? The thread will be in both WaitSleepJoin and the AbortRequested states at the same time. As soon as the thread returns from a call to Sleep or is interrupted, the thread receives a ThreadAbortException to begin aborting.

Thread Priority

System.Threading.Thread.Priority enumeration defines the priority states of a thread that in turn determines how much processor time a thread gets to execute. Threads are executed based on their priority levels. High priority threads always get more processor time than their counterparts. If there is more than one thread at a high priority then the operating system cycles through the threads giving each high priority thread some amount of processor time. Lower priority threads do not get to execute as long as a higher priority thread is available. When there are no more threads of higher priority, the operating system then selects the next lower priority threads for execution. If at any point it encounters a higher priority thread, then the lower priority threads are preempted and give way to the higher priority thread to execute. Any new thread gets created with a Normal priority. You can then change the priority value to any of the values shown below (these are defined in the Priority property of the Thread class):

  • Highest
  • AboveNormal
  • Normal
  • BelowNormal
  • Lowest

Conclusion:

This part was just the beginning to understand how threads are created and what properties they have. The System.Threading namespace has a lot many interesting features like locking a thread object, interprocess synchronization, classes that manage a groups of threads, or deadlock resolution. We would study these advanced features in the coming series.

Comment Request!
Thank you for reading this post. Please post your feedback, question, or comments about this post Here.
Login to add your contents and source code to this article
 [Top] Rate this article
 
 About the author
 
Manisha Mehta
Looking for C# Consulting?
C# Consulting is founded in 2002 by the founders of C# Corner. Unlike a traditional consulting company, our consultants are well-known experts in .NET and many of them are MVPs, authors, and trainers. We specialize in Microsoft .NET development and utilize Agile Development and Extreme Programming practices to provide fast pace quick turnaround results. Our software development model is a mix of Agile Development, traditional SDLC, and Waterfall models.
Click here to learn more about C# Consulting.
 
Introducing MaxV - one click. infinite control. Hyper-V Hosting from MaximumASP.
Finally – a virtual platform that delivers next-generation Windows Server 2008 Hyper-V virtualization technology from a managed hosting partner you can truly depend on. Visit www.maximumasp.com/max for a FREE 30 day trial. Hurry offer ends soon. Climb aboard the MaxV platform and take advantage of High Availability, Intelligent Monitoring, Recurrent Backups, and Scalability – with no hassle or hidden fees. As a managed hosting partner focused solely on Microsoft technologies since 2000, MaximumASP is uniquely qualified to provide the superior support that our business is built on. Unparalleled expertise with Microsoft technologies lead to working directly with Microsoft as first to offer IIS 7 and SQL 2008 betas in a hosted environment; partnering in the Go Live Program for Hyper-V; and product co-launches built on WS 2008 with Hyper-V technology.
Dynamic PDF
ceTE software specializes in components for dynamic PDF generation and manipulation. The DynamicPDF™ product line allows you to dynamically generate PDF documents, merge PDF documents and new content to existing PDF documents from within your applications.
Discover the Top 5 .NET Memory Management Fundamentals
To write the best .NET code, you need to know exactly how the .NET framework really manages memory. Ricky Leeks presents the Top 5 fundamental facts of .NET memory management. Learn more.
Nevron Chart for .NET 2010.1 Now Available
The leading .NET charting control now features PDF, Flash and Silverlight export, visualization of large datasets and more. Deliver true charting functionality to your BI, Scorecard, Presentation or Scientific apps. Download evaluation now.
ASP.NET 4 Hosting
Get 2 Months Free of ASP.NET Hosting for Only $4.95/month! Receive FREE MS SQL and MySQL Databases Including ASP.NET 4/3.5, MVC 3.0, Silverlight 4, Windows 2008/IIS 7.0 Plus FREE IIS 7 Modules. Host UNLIMITED ASP.NET Web Sites – Click Here!
 
 Post a Feedback, Comment, or Question about this article
Subject:
Comment:
Nevron Chart
Become a Sponsor
 Comments
very good ! by DynV On July 20, 2007
very good but sometimes too condensed thus hard to understand, thanks for sharing this knowledge.
Reply | Email | Modify 
6 Months Free & No Setup Fees ASP.NET Hosting!
 © 2012  contents copyright of their authors. Rest everything copyright Mindcracker. All rights reserved.