1. A native thread is a Win32 thread which created by Windows OS where as a managed thread is a thread created by .NET Framework.
2. But is there a difference... after all a managed thread would be a simple wrapper around Win32 thread ?
a. Yes, there is a difference. With version 1.0 and version 1.1 of the CLR, each Thread object is associated with its own physical Win32® thread. Note that future versions of the CLR are likely to provide an optimization whereby it will not be necessary to create a separate physical thread for each Thread object.
b. And creating an object from the Thread class doesn't actually create a physical thread. Instead, you must call the Thread object's Start method for the CLR to call to the Windows OS and create a physical thread.
3. There is an overhead involved in creating and destroying physical threads.
4. The lifetime of this physical thread is controlled by the target method's execution. When execution of the method completes, the CLR gives control of the physical thread back to Windows. At this point, the OS destroys the physical thread.
Creating secondary thread1. The
Thread class is used to create secondary threads.
2. It takes an object of
ThreadStart delegate
public delegate void ThreadStart();
3. To pass parameters to thread you have two options
a. Use
ParameterizedThreadStartb. Create a custom thread class with a parameterized constructor. When you create an object from a custom thread class, you can initialize it with whatever parameter values are required in your particular situation.
class Program {
static void Main(string[] args) {
ThreadStart st = new ThreadStart(new A().ThreadMethod);
System.Threading.Thread th = new System.Threading.Thread(st);
th.IsBackground = true;
th.Start();
}
}
class A {
public void ThreadMethod() {
Thread.Sleep(-1);
}
}
Lifecycle of a Thread
1. When you create a thread and have not called the Start method, the state of the thread is
Unstarted.
2. After you call the Start method,
a. If the thread is a background thread the state is
Backgroundb. If the thread is a foreground thread the state is
Runningc. If the thread is sleeping, the state is
WaitSleepJoin3. A thread in
WaitSleepJoin is also called
blocked thread i.e. it waits or pauses for a result. Once blocked, a thread immediately relinquishes its allocation of CPU time and doesn’t get re-scheduled until unblocked.
A thread, while blocked, doesn't consume CPU resources. A thread can enter blocked by calling
a. Thread.Sleep
b. Thread.Join
c. Thread Synchronization Blocking (Lock, Mutex, Semaphore) or Signaling Constructs (WaitHandles)
Thread Methods1. public void Join();
2. public bool Join(int millisecondsTimeout);
Blocks the calling thread until a thread terminates or the specified time elapses, while continuing to perform standard COM and SendMessage pumping.
3. public void Abort();
4. public void Interrupt();
5. The Resume and Suspend methods have been suspended.
Interrupts a thread that is in the WaitSleepJoin thread state.
Handling Exceptions1. Exceptions from secondary threads are never passed to other threads i.e. each thread should handle its own exceptions.
2. From .NET 2.0 onwards, an unhandled exception on any thread shuts down the whole application, meaning ignoring the exception is generally not an option. Hence a
try/catch block is required in every thread entry method – at least in production applications – in order to avoid unwanted application shutdown in case of an unhandled exception.
3.
Application.ThreadException which is global exception handler in Windows Forms applications do not get exceptions raised by worker threads. The .NET framework provides a lower-level event for global exception handling:
AppDomain.UnhandledException. This event fires when there's an unhandled exception in any thread, and in any type of application (with or without a user interface).
When to create a secondary threadYou should be creating and managing secondary threads to execute methods asynchronously only when you cannot use delegates.
1. You need to execute a long-running task
When you need to dedicate a thread to a task that's going to take a long time, you should create a new thread. It would be considered bad style to use delegates because you would effectively be taking a thread out of the CLR thread pool and never returning it. Asynchronous method execution using delegates should only be used for relatively short-running tasks.
2. You need to adjust a thread's priority
3. You need a foreground thread that will keep a managed desktop application alive
Each Thread object has an IsBackground property that indicates whether it is a background thread. All the threads in the CLR thread pool are background threads and should not be modified in this respect. That means a task executing asynchronously as a result of a call to BeginInvoke on a delegate is never important enough by itself to keep an application alive.
4. You need a single-threaded apartment (STA) thread to work with apartment-threaded COM objects.
5. Use a dedicated thread if you want to abort it prematurely by calling
Thread's Abort method.