Walk Through Threading in C#:
After a long time I got a chance to write,I felt this is the topic to be most required to discuss,below simple & I would say light weight data would make you to digest threading concepts in C#,
After a long time I got a chance to write,I felt this is the topic to be most required to discuss,below simple & I would say light weight data would make you to digest threading concepts in C#,
A thread is defined as the
execution path of a program. Each thread defines a unique flow of control.
With the help of threads we can
increase the response time of the application.
Thread
Life Cycle
The life cycle of a thread starts when
an object of the System.Threading.Thread class is created and ends when the
thread is terminated or completes execution.
Following are the various states in the
life cycle of a thread:
- The Unstarted State: it is the situation when the instance of the thread is created but the Start method has not been called.
- The Ready State: it is the situation when the thread is ready to run and waiting CPU cycle.
- The Not Runnable State: a thread is not runnable, when:
- Sleep method has been called
- Wait method has been called
- Blocked by I/O operations
- The Dead State: it is the situation when the thread has completed execution or has been aborted.
The Main Thread:
System.Threading.Thread class is used
for working with threads.
When a C# program starts execution,
the main thread is automatically created.
You can access a thread using the CurrentThread property of the Thread
class.
Nice Example illustrates you the
point:
static void Main(string[]
args)
{
{
Thread th = Thread.CurrentThread;
th.Name = "MainThread";
Console.WriteLine("This is {0}", th.Name);
Console.ReadKey();
}
th.Name = "MainThread";
Console.WriteLine("This is {0}", th.Name);
Console.ReadKey();
}
o/p:
This is MainThread
Creating Threads:
Threads are created by
extending the Thread class. The extended Thread class then calls the Start() method to begin the child
thread execution.
The following program
demonstrates the concept:
class Program
{
public static void CallToChildThread()
{
Console.WriteLine("Child thread starts");
}
{
public static void CallToChildThread()
{
Console.WriteLine("Child thread starts");
}
static void Main(string[] args)
{
ThreadStart childref = new ThreadStart(CallToChildThread);
Console.WriteLine("In Main: Creating the Child thread");
Thread childThread = new Thread(childref);
childThread.Start();
Console.ReadKey();
}
{
ThreadStart childref = new ThreadStart(CallToChildThread);
Console.WriteLine("In Main: Creating the Child thread");
Thread childThread = new Thread(childref);
childThread.Start();
Console.ReadKey();
}
}
o/p: In Main: Creating the Child thread
Child thread starts
Managing Threads:
public static void
CallToChildThread()
{
Console.WriteLine("Child thread
starts");
// the thread is paused for 5000
milliseconds
int
sleepfor = 5000;
Console.WriteLine("Child Thread Paused for
{0} seconds",
sleepfor / 1000);
Thread.Sleep(sleepfor);
Console.WriteLine("Child thread
resumes");
}
static void Main(string[] args)
{
ThreadStart childref = new ThreadStart(CallToChildThread);
Console.WriteLine("In Main: Creating the Child thread");
Thread childThread = new Thread(childref);
childThread.Start();
Console.ReadKey();
}
static void Main(string[] args)
{
ThreadStart childref = new ThreadStart(CallToChildThread);
Console.WriteLine("In Main: Creating the Child thread");
Thread childThread = new Thread(childref);
childThread.Start();
Console.ReadKey();
}
O/p:
Destroying Threads:
The Abort() method is used for destroying threads.
The runtime aborts the thread
by throwing a ThreadAbortException.
This exception cannot be caught, the control is sent to the finally
block, if any.
public static void
CallToChildThread()
{
try
{
Console.WriteLine("Child thread starts");
// do some work, like counting to 10
for (int counter = 0; counter <= 10; counter++)
{
Thread.Sleep(500);
Console.WriteLine(counter);
}
{
try
{
Console.WriteLine("Child thread starts");
// do some work, like counting to 10
for (int counter = 0; counter <= 10; counter++)
{
Thread.Sleep(500);
Console.WriteLine(counter);
}
//So here in this child thread it
makes 3 trips (after every 500 ms..when it starts doning for 4th
//Main thread Sleep time got copleted so main thread become active
Console.WriteLine("Child Thread Completed");
//Main thread Sleep time got copleted so main thread become active
Console.WriteLine("Child Thread Completed");
}
catch (ThreadAbortException e)
{
Console.WriteLine("Thread Abort Exception");
}
finally
{
Console.WriteLine("Couldn't catch the Thread Exception");
}
}
static void Main(string[] args)
{
ThreadStart childref = new ThreadStart(CallToChildThread);
Console.WriteLine("MainThread: Creating the Child thread");
Thread childThread = new Thread(childref);
childThread.Start();
//stop the main thread for some time
//For this period Child thread will execute
Thread.Sleep(2000);
//now abort the child
Console.WriteLine("MainThread: Aborting the Child thread");
childThread.Abort();
Console.ReadKey();
}
catch (ThreadAbortException e)
{
Console.WriteLine("Thread Abort Exception");
}
finally
{
Console.WriteLine("Couldn't catch the Thread Exception");
}
}
static void Main(string[] args)
{
ThreadStart childref = new ThreadStart(CallToChildThread);
Console.WriteLine("MainThread: Creating the Child thread");
Thread childThread = new Thread(childref);
childThread.Start();
//stop the main thread for some time
//For this period Child thread will execute
Thread.Sleep(2000);
//now abort the child
Console.WriteLine("MainThread: Aborting the Child thread");
childThread.Abort();
Console.ReadKey();
}
O/p:
Let us observe the below examples:
Ex:
class Program
{
static void Main()
{
Thread t = new Thread(WriteY); // Kick off a new thread
t.Start(); // running WriteY()
//Thread.Sleep(1000);
// Simultaneously, do something on the main thread.
for (int i = 0; i < 100; i++)
Console.Write("x");
Console.ReadKey();
}
static void WriteY()
{
for (int i = 0; i < 100; i++) Console.Write("y");
}
}
{
static void Main()
{
Thread t = new Thread(WriteY); // Kick off a new thread
t.Start(); // running WriteY()
//Thread.Sleep(1000);
// Simultaneously, do something on the main thread.
for (int i = 0; i < 100; i++)
Console.Write("x");
Console.ReadKey();
}
static void WriteY()
{
for (int i = 0; i < 100; i++) Console.Write("y");
}
}
O/p:
xxxxxxxxxxxxxxxxyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxyyyyyyyyyyyyy
yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy
yyyyyyyyyyyyyxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
...
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxyyyyyyyyyyyyy
yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy
yyyyyyyyyyyyyxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
...
The main thread creates a new thread t on which it runs a
method that repeatedly prints the character “y”. Simultaneously, the main
thread repeatedly prints the character “x”:
I have commented Thread.Sleep(1000),if
you uncomment it then the Main Thread will be in sleep mode in that time writeY
thread got executed,Just test it to know….
Ex:
static bool done; // Static fields
are shared between all threads
static void Main()
{
//new Thread(Go).Start();
//Go();//if your using static keyword for Go()
Program tt = new Program(); // Create a common instance
new Thread(tt.Go).Start();
tt.Go();
Console.Read();
}
void Go()
{
if (!done) { done = true; Console.WriteLine("Done");
}
}
static void Main()
{
//new Thread(Go).Start();
//Go();//if your using static keyword for Go()
Program tt = new Program(); // Create a common instance
new Thread(tt.Go).Start();
tt.Go();
Console.Read();
}
void Go()
{
if (!done) { done = true; Console.WriteLine("Done");
}
}
O/p:
Done
void
Go()
{
if (!done) { Console.WriteLine("Done"); done = true; }
}
Then out put changes to :
O/p:
{
if (!done) { Console.WriteLine("Done"); done = true; }
}
Then out put changes to :
O/p:
Done
Done
Now,you would feel oohhh..!! How can it be..???
The problem is that one thread can be evaluating the
if
statement right as the other thread is executing the WriteLine
statement —
before it’s had a chance to set done
to true.
How to avoid..??
The remedy is to obtain an lock while reading and writing to the common field.
C# provides the lock statement for this purpose.
Below same program with lock get fixes your problem:
Ex:
static bool done; // Static fields
are shared between all threads
static readonly object locker = new object();
static void Main()
{
//new Thread(Go).Start();
//Go(); //if your using static method for Go() then this is correct
Program tt = new Program(); // Create a common instance
new Thread(tt.Go).Start();
tt.Go();
Console.Read();
}
void Go()
{
lock (locker)
{
if (!done) { Console.WriteLine("Done"); done = true; }
}
}
static readonly object locker = new object();
static void Main()
{
//new Thread(Go).Start();
//Go(); //if your using static method for Go() then this is correct
Program tt = new Program(); // Create a common instance
new Thread(tt.Go).Start();
tt.Go();
Console.Read();
}
void Go()
{
lock (locker)
{
if (!done) { Console.WriteLine("Done"); done = true; }
}
}
Join and Sleep:
As you know Sleep() is used to
stop the thread and simultaneously other thread got executed but For ex: If I don’t
know at what time should this thread A need to be kept in sleep mode to execute
thread B,then after starting thread A just use Join() then thread B after completion automatically returns to the state where it
was started and execute the remaining statement in thread B.
Ex:
static void Main()
{
Thread t = new Thread(Go);
t.Start();
t.Join();
Console.WriteLine("Thread t has ended!");
Console.Read();
}
static void Go()
{
for (int i = 0; i < 2; i++) Console.Write("y");
}
{
Thread t = new Thread(Go);
t.Start();
t.Join();
Console.WriteLine("Thread t has ended!");
Console.Read();
}
static void Go()
{
for (int i = 0; i < 2; i++) Console.Write("y");
}
This prints “y” 1,000 times,
followed by “Thread t has ended!” immediately afterward.
Pass Data to the thread in this way:
Ex:
static void Main()
{
Thread t = new Thread(() => Print("Hello from t!"));
t.Start();
Console.Read();
}
{
Thread t = new Thread(() => Print("Hello from t!"));
t.Start();
Console.Read();
}
static void Print(string
message)
{
Console.WriteLine(message);
}
{
Console.WriteLine(message);
}
With this
approach, you can pass in any number of
arguments to the method. You can even wrap the entire implementation in a multi-statement lambda:
Ex:
new Thread (() =>
{
Console.WriteLine ("I'm running on another thread!");
Console.WriteLine ("This is so easy!");
Ex:
new Thread (() =>
{
Console.WriteLine ("I'm running on another thread!");
Console.WriteLine ("This is so easy!");
}).Start();
Now let us discuss Multithreading:
Now let us discuss Multithreading:
Multi Threading:
There is not a big deal in understanding Multi threading after above examples, for a long time, most programming applications (except for embedded system programs) were single-threaded. That means there was only one thread in the entire application. You could never do computation A until completing computation B.
But,Multi threading allows you to do the Computations at a time. Then surely it makes your performance twice.
Below Example illustrates you the Multi Threading concept, Handling of the threads in Multithreading can be done in difference way
(Note: Uncomment the statements to understand more about handling threads by setting through prority,locks..)
//static readonly object locker =
new object();
public static void Thread1()
{
//lock (locker)
//{
for (int i = 0; i < 5; i++)
{
Console.WriteLine("Thread1 Task-{0} Finished", i);
}
//}
}
public static void Thread2()
{
//lock (locker)
//{
for (int i = 0; i < 5; i++)
{
Console.WriteLine("Thread2 Task-{0} Finished", i);
}
//}
}
}
public class MyClass
{
public static void Main()
{
Console.WriteLine("Before start thread");
Thread tid1 = new Thread(new ThreadStart(MyThread.Thread1));
Thread tid2 = new Thread(new ThreadStart(MyThread.Thread2));
//tid2.Priority = ThreadPriority.Highest;
tid1.Start();
tid2.Start();
Console.ReadKey();
}
O/p:
public static void Thread1()
{
//lock (locker)
//{
for (int i = 0; i < 5; i++)
{
Console.WriteLine("Thread1 Task-{0} Finished", i);
}
//}
}
public static void Thread2()
{
//lock (locker)
//{
for (int i = 0; i < 5; i++)
{
Console.WriteLine("Thread2 Task-{0} Finished", i);
}
//}
}
}
public class MyClass
{
public static void Main()
{
Console.WriteLine("Before start thread");
Thread tid1 = new Thread(new ThreadStart(MyThread.Thread1));
Thread tid2 = new Thread(new ThreadStart(MyThread.Thread2));
//tid2.Priority = ThreadPriority.Highest;
tid1.Start();
tid2.Start();
Console.ReadKey();
}
O/p:
Friends I hope you have got an idea about threading now….
there are still many things to discuss in this topic but ,
I would feel these is enough to start.
No comments:
Post a Comment