![]() |
General Programming »
Threads, Processes & IPC »
Threading
Intermediate
Understanding Threading in .NET FrameworkBy Chandrakant ParmarThreading in .NET Framework at a glance. |
C#, Windows, .NET, Visual Studio, Dev
|
|
Advanced Search |
|
|
|
||||||||||||||||
This article describes thread basics covering the following areas:
System.Thread() class and create an instance.
object.Join() to join threads.
object.Sleep(<No of seconds>) to suspend a thread.
object.Abort() to abort a thread.
Interlocked class which uses Increment and Decrement methods to increment and decrement values. Thread Synchronization is explained covering the following:
enter() method of the monitor passing the object we want to monitor. We can explicitly choose the wait() method of the monitor to control thread ordering. In case of using wait(), the waiting threads will be allowed to be notified of a chance to run again if the active thread calls Pulse(). This signals the CLR that there has been a chance in the state that might free a thread that is waiting. The CLR tracks the fact that the earlier thread asked to wait, and the thread will be guaranteed access in the order in which the waits were requested. Exit() can be called once when the thread is finished with the monitor. In this article, we are going to look into the basics and advance concepts about Microsoft .NET Framework based Threading support. Refer to the previous article for details about the Microsoft .NET framework.
Threading is one of the integral parts of the Microsoft .NET Framework based Common Language Runtime. Refer to the previous article on .NET Framework for more details.

Threading support is in-built under the Common Language Runtime provided by the Microsoft .NET Framework.
System.Threading.
Create a new instance of the Thread object. The Thread constructor accepts one parameter that is a delegate. MS CLR provides the ThreadStart delegate class for starting the thread.
Example:
Thread myThread = new Thread( new ThreadStart(myFunc) );
To run this thread, we need the following:
Thread t1 = new Thread( new ThreadStart(Incrementer) );
To instantiate this, we need the following:
t1.Start( );
A detailed example is as below:
namespace Programming_CSharp
{
using System;
using System.Threading;
class Tester
{
static void Main( )
{
// make an instance of this class
Tester t = new Tester( );
// run outside static Main
t.DoTest( );
}
public void DoTest( )
{
// create a thread for the Incrementer
// pass in a ThreadStart delegate
// with the address of Incrementer
Thread t1 = new Thread(new ThreadStart(Incrementer) );
// create a thread for the Decrementer
// pass in a ThreadStart delegate
// with the address of Decrementer
Thread t2 = new Thread(new ThreadStart(Decrementer) );
// start the threads
t1.Start( );
t2.Start( );
}
// demo function, counts up to 1K
public void Incrementer( )
{
for (int i =0;i<1000;i++)
{
Console.WriteLine("Incrementer: {0}", i);
}
}
// demo function, counts down from 1k
public void Decrementer( )
{
for (int i = 1000;i>=0;i--)
{
Console.WriteLine("Decrementer: {0}", i);
}
}
}
}
Output:
Incrementer: 102
Incrementer: 103
Incrementer: 104
Incrementer: 105
Incrementer: 106
Decrementer: 1000
Decrementer: 999
Decrementer: 998
Decrementer: 997
Once a thread starts running and in some situation if we need to tell the thread to stop processing and wait until a second thread completes processing, we need to join the first thread to the second thread. Use the following for the same. This will join the second thread to the first one.
Example:
t2.Join( );
In some situations, we might want to suspend a running thread.
Example:
t2..Sleep(<No of Seconds>);
Threads has to die after the execution of the process in normal situations, occasionally it is required for the programmer to kill a thread. Threads can be killed using the following:
Example:
t2.Abort();
In some situations, we need to synchronize the running threads so we can modify the running thread and its resources.
namespace Programming_CSharp
{
using System;
using System.Threading;
class Tester
{
private int counter = 0;
static void Main( )
{
// make an instance of this class
Tester t = new Tester( );
// run outside static Main
t.DoTest( );
}
public void DoTest( )
{
Thread t1 = new Thread( new ThreadStart(Incrementer) );
t1.IsBackground=true;
t1.Name = "ThreadOne";
t1.Start( );
Console.WriteLine("Started thread {0}",
t1.Name);
Thread t2 = new Thread( new ThreadStart(Incrementer) );
t2.IsBackground=true;
t2.Name = "ThreadTwo";
t2.Start( );
Console.WriteLine("Started thread {0}", t2.Name);
t1.Join( );
t2.Join( );
// after all threads end, print a message
Console.WriteLine("All my threads are done.");
}
// demo function, counts up to 1K
public void Incrementer( )
{
try
{
while (counter < 1000)
{
int temp = counter;
temp++; // increment
// simulate some work in this method
Thread.Sleep(1);
// assign the decremented value
// and display the results
counter = temp;
Console.WriteLine("Thread {0}. Incrementer: {1}",
Thread.CurrentThread.Name, counter);
}
}
catch (ThreadInterruptedException)
{
Console.WriteLine("Thread {0} interrupted! Cleaning up...",
Thread.CurrentThread.Name);
}
finally
{
Console.WriteLine("Thread {0} Exiting. ", Thread.CurrentThread.Name);
}
}
}
}
Output:
>Started thread ThreadOne
Started thread ThreadTwo
Thread ThreadOne. Incrementer: 1
Thread ThreadOne. Incrementer: 2
Thread ThreadOne. Incrementer: 3
Thread ThreadTwo. Incrementer: 3
Thread ThreadTwo. Incrementer: 4
Thread ThreadOne. Incrementer: 4
Thread ThreadTwo. Incrementer: 5
Thread ThreadOne. Incrementer: 5
Thread ThreadTwo. Incrementer: 6
Thread ThreadOne. Incrementer: 6
Interlocked just for the reason of locking. This consists of two methods: Increment and Decrement. Example:
public void Incrementer( )
{
try
{
while (counter < 1000)
{
Interlocked.Increment(ref counter);
// simulate some work in this method
Thread.Sleep(1);
// assign the decremented value
// and display the results
Console.WriteLine("Thread {0}. Incrementer: {1}",
Thread.CurrentThread.Name, counter);
}
}
}
Output (excerpts):
Started thread ThreadOne
Started thread ThreadTwo
Thread ThreadOne. Incrementer: 1
Thread ThreadTwo. Incrementer: 2
Thread ThreadOne. Incrementer: 3
Thread ThreadTwo. Incrementer: 4
Thread ThreadOne. Incrementer: 5
Thread ThreadTwo. Incrementer: 6
Thread ThreadOne. Incrementer: 7
Thread ThreadTwo. Incrementer: 8
Thread ThreadOne. Incrementer: 9
Thread ThreadTwo. Incrementer: 10
Thread ThreadOne. Incrementer: 11
Thread ThreadTwo. Incrementer: 12
Thread ThreadOne. Incrementer: 13
Thread ThreadTwo. Incrementer: 14
Thread ThreadOne. Incrementer: 15
Thread ThreadTwo. Incrementer: 16
Thread ThreadOne. Incrementer: 17
Thread ThreadTwo. Incrementer: 18
Thread ThreadOne. Incrementer: 19
Thread ThreadTwo. Incrementer: 20
A lock marks a critical section of the code, and provides synchronization to an object.
Example:
public void Incrementer( )
{
try
{
while (counter < 1000)
{
lock (this)
{
int temp = counter;
temp ++;
Thread.Sleep(1);
counter = temp;
}
// assign the decremented value
// and display the results
Console.WriteLine("Thread {0}. Incrementer: {1}",
Thread.CurrentThread.Name, counter);
}
}
There are situations where the programmer need to monitor the running threads, for which we can use the following:
Monitor.Enter(this);
There are situations when the process goes for a deadlock situation. Synchronization is a little tricky to handle in such cases.
Join() and using Monitor(), Wait() etc� In situations when one thread is dependent on another thread's completion, it is some times possible that unknowingly one thread can wait for the other to finish, so the second thread can go ahead and run the second process. In few occasions, each thread may go in a loop to wait for the next thread to complete the processing to start, where both the threads are waiting for each other to complete and none of them is actually doing any processing.
| You must Sign In to use this message board. | |||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||
General
News
Question
Answer
Joke
Rant
Admin
|
PermaLink |
Privacy |
Terms of Use
Last Updated: 24 Apr 2005 Editor: Smitha Vijayan |
Copyright 2005 by Chandrakant Parmar Everything else Copyright © CodeProject, 1999-2009 Web18 | Advertise on the Code Project |