Developing Multi-Threaded .NET Applications

Are you preparing for IT certification? With practice questions, study notes, interactive quizzes, tips and technical articles, uCertify PrepKits ensure that you get a solid grasp of core technical concepts to ace your certification exam in first attempt.

Developing Multi-Threaded .NET Applications

Rating:

Introduction

A thread is a sequence of code execution within a single process. It does not have its own address space. However, it uses the memory and other resources of the process in which it executes. A thread consists of identification, a stack, a register set containing the program or the instruction pointer, the stack pointer, and a priority. A process can have multiple threads that execute independently and concurrently with its own sequence of instructions. Therefore, multiple operations are performed concurrently within a single process and each operation is treated as a thread. Multiple operations are also referred to as multi-threaded operations.

In a multi-threaded operation, all threads in a single process exist in the same address space and share all the resources belonging to the process. A thread can create, suspend, resume, terminate, or change the priority of another thread within a single process. A thread can kill its process by canceling the main or primary thread. Therefore, canceling the main thread terminates all the threads of the process. If any changes occur to the main thread, it can also affect all the threads of the process. Even the priority of the process, when changed, can also change the priorities of all threads that inherited.

The .NET Framework supports a multi-threaded operation in developing .NET applications. Multiple threads within a single process can manage the multi-tasks of an application. As compared to multiple processes, multiple threads can increase the throughput of an application and simplify program structure. In a multi-threaded operation, the application does not require any special mechanism to communicate between its tasks, and less system resources are needed for context switching between the tasks.

Advantages and Disadvantages of Using Multiple Threads

Multiple threads can accomplish various tasks while working in a single application domain. They can communicate to a Web server and a database over a network. They can perform operations that are time taking and can distinguish various tasks of varying priority. Multiple threads also enable the user interface to be more responsive during the time allocation of background tasks.

However, one should avoid using multiple threads in a single application domain, as the consumption of operating-system resources can be minimized and the application performance enhanced. The frequent use of threads can cause the computer to consume more memory. There are a limited number of processes that require the context information, AppDomain objects, and threads according to the storage space in the memory. It is also very difficult to keep track of large number of threads, as it consumes significant processor time. Therefore, if there are multiple threads executing in a single process, threads in other processes get less frequent time period for execution.

Furthermore, several errors can occur in the source code while controlling code execution with large number of threads. Similarly, a large number of threads can also cause conflicts when different resources are shared among multiple threads. In order to avoid these conflicts, it is better to control access to shared resources by providing synchronization objects. By synchronization objects, one can coordinate resources that are shared among multiple threads. Therefore, the number of threads should be reduced to make it easier to synchronize resources. The resources that require synchronization can include the following:

  • System resources, e.g. communication ports

  • Resources that are shared by more than one process, e.g. file handles

  • Resources of an application domain shared by multiple threads, e.g. global, static, and instance fields
Creating Threads

The .NET Framework provides the System.Threading namespace, which contains classes that are used to create and manage multiple threads in an application. The Thread class of the System.Threading namespace represents a single thread and creates and controls the thread in a process. It sets a thread's priority and gets the status of that thread. Some of the major methods of the Thread class are as follows:

Method NameDescription
AbortRaises a ThreadAbortException exception on the thread that is being invoked and begins the process of the thread's termination.
InterruptRaises a ThreadInterruptedException exception when a thread is interrupted or when the thread is in a blocked state, i.e. in a wait, sleep, or join state.
JoinBlocks the thread that is recently being called until the previous thread terminates.
StartSets a thread to execute.
SleepBlocks the current thread for a specified time period (in milliseconds). Allows the execution of other threads.
SpinWaitBlocks the current thread for a certain number of iterations. Does not allow the execution of other threads.

Some of the major properties of the Thread class are as follows:

Property NameDescription
IsAliveReturns a value of the current thread that is recently executing.
IsBackgroundGets a value to indicate whether or not the thread is running as a background thread.
IsThreadPoolThreadGets a value to indicate whether or not a thread belongs to the thread pool.
ManagedThreadIdReturns a unique identifier to identify the currently managed thread.
NameReturns a string that contains the name of the thread.
PriorityReturns a value to indicate the thread's priority. The default property value is Normal.
ThreadStateGets a value to indicate the state of the current thread.

The following code snippet displays a simple multi-threaded processing in a process:

using System;
using System.Threading;
public class ThreadProcess1
{
 public static void Thread1()
 {
   Console.Write("Enter your first name");
   string fname = Console.ReadLine();
   Console.WriteLine("The length of your first name is: {0}", fname.Length);
   Thread.Sleep(0);
 }
 public static void Thread2()
 {
   Console.Write("Enter your last name");
   string lname = Console.ReadLine();
   Console.WriteLine("The length of your last name is: {0}", lname.Length);
   Thread.Sleep(0);
 }
 public static void Main()
 {
   Console.WriteLine("Start a thread.");
   Thread t1 = new Thread(new ThreadStart(Thread1));
   t1.Start();
   Thread.Sleep(0);
   Console.WriteLine("Wait until the first task ends.");
   t1.Join();
   Console.WriteLine("Start another thread.");
   Thread t2 = new Thread(new ThreadStart(Thread2));
   t2.Start();
   Thread.Sleep(0);
   t2.Join();
   Console.WriteLine("Press Enter to end program.");
   Console.ReadLine();
   }
}


Thread Pooling

The .NET Framework provides a class known as the ThreadPool in the System.Threading namespace. This class provides a pool of threads that are used to post work items and process asynchronous I/O and timers. Thread pooling is a technique that uses threads more efficiently by providing a pool of worker threads that are managed by the system. There is one such thread in the thread pool, which monitors the status of several wait operations that are queued to the thread pool. When a wait operation completes, a worker thread starts executing the corresponding callback function.

Note: Background threads are those threads that are executed from the managed thread pool. There is only one thread pool in a single process. By default, the size of a thread pool is 25 threads per processor.

Thread Priorities

Since the Windows operating system is designed to optimize the scheduling of threads, a developer can adjust a thread's scheduling priority in order to reduce bottlenecks and allow blocked threads to run. A thread determines its priority property to determine the manner in which the time can slice its processor time for its execution. The ability of the operating system is to allocate longer time slices to those threads that have high priority properties and shorter time slices to threads with low priority properties. In .NET infrastructure, the Priority property of the Thread class returns a value to indicate the thread's priority. It accepts values from the ThreadPriority enumeration. Each thread in a process has a priority within the range between the Lowest and the Highest value. By default, the value of a thread's priority is Normal. A thread in its state of execution can be assigned in any of the following values:
  • Highest

  • AboveNormal

  • Normal

  • BelowNormal

  • Lowest
States of Threads

A thread in a thread pool can be in any one of the states of execution. The ThreadState enumeration of the System.Threading namespace specifies the execution state of each thread in a thread pool. The ThreadState enumeration has the following members that describe the various execution states of a thread:

Member NameDescription
AbortedSpecifies the thread to be in the Stopped state.
AbortRequested Requests the thread to be aborted. But the thread has not yet received the ThreadAbortException exception that causes the thread to terminate.
BackgroundSpecifies the execution of a thread as a background thread.
RunningIndicates that the thread has been started and it is not blocked.
StoppedIndicates that the thread has been stopped.
StopRequestedRequests the thread to stop.
SuspendedIndicates that the thread has been suspended.
SuspendRequestedRequests the thread to suspend.
UnstartedIndicates that the thread has been created, but the Thread.Start method has not been called on the thread.
WaitSleepJoinIndicates that the thread is blocked, as the Monitor.Wait, Thread.Sleep, or Thread.Join method is called each on separate threads.

The .NET Framework provides a property in the Thread class known as the ThreadState property that retrieves one of the values indicating the state of the current thread in a process. The state of a current thread can be illustrated in the figure given below:


Thread Synchronization

Thread synchronization is a process through which multiple threads share access to common resources. In a .NET multi-threaded application, individual threads sometimes need to be synchronized with other parts of the application program. For example, if multiple threads access the same resources for both read and write operations, the resultant value can be incorrect. If a thread writes the contents to a file and another thread reads the contents from the same file at the same time, data can become corrupted. In such a situation, the file access needs to be locked, until at least one thread completes its execution before letting the other thread to start its execution.

The Microsoft .NET Framework has provided many thread synchronization objects. One such thread synchronization object is Mutex, which enables only one thread to access the resource at a time. Another thread synchronization object is Semaphore, which allows zero to any number of threads to access the resource simultaneously.

In a .NET application, the synchronization technique is used to control the order in which the lines of program code run when a set of tasks are to be performed in a specific sequence. The technique can also be used to prevent the problems that can arise when two or more threads share the same resources at the same time.


Rating:



Other articles

Click here to Article home

 
uCertify.com | Our Company | Articles | Privacy | Security | Contact Us | News and Press Release | uCertify India
MCSE: MCSA, MCTS, MCITP    JAVA Certification: SCJP, SCWCD Cisco Certification: CCNA, CCENT, A+, Network+, Security+
Oracle Certification: OCP 9i, OCP 10g, OCA 9i, OCA 10g CIW foundation    EC-212-32    CISSP    Photoshop ACE    Adobe Flash ACE
© 2008 uCertify.com. All rights reserved. All trademarks are the property of their respective owners.