The threads class is used to create and manipulate managed threads. In the .NET environment, it is the same class used for all .NET enabled languages. The .NET threads catch all the threads executed in the managed threads. We can't access the unmanaged threads from the managed threads.
Thread.GetHashCode is used to find the managed threads. Managed threads are executed in the .NET Common Language Runtime environment. Microsoft doesn't recommend mixing managed and unmanaged threads.
Managed threads start when the
System.Threading.Thread.Start method is called. This method is used to start the managed threads. When a user creates the threads, we can use
ThreadStart delegate or a
ParameterizedThreadStart delegate for creating the threads. The
ThreadStart delegate is used to start the thread without any parameters. We can pass the argument using the
ParameterizedThreadStart delegate is used to create a thread to pass an
Object as an argument. If we call the
Start method more than once, it throws a
ThreadStateException exception. The following example shows how to create the managed threads:
ref class ThreadClass
static void ThraedClassMethod()
ThreadClass ^ objclass = gcnew ThreadClass;
ThreadStart^ mThread = gcnew ThreadStart(objclass,&objclass::ThreadClasMethod);
Thread^ newThread = gcnew Thread(mThread);
IsAlive properties are used to get a thread state. But Microsoft doesn't recommend using those methods as thread synchronization. The
System.Threading.Thread.Sleep method is used to sleep the thread for current execution. We can't sleep another thread from thread function. The
System.Threading.Timeout.Infinite waits for an infinite level or when calls to other threads are returned. If
System.Threading.Thread.Abort is called, it will terminate.
In Managed threads, we will set thread priorities much like unmanaged threads. CLR assigned
ThreadPriority.Normal for default level. We can get or set the priority of any thread with the
Thread.Priority property. The
Abort method is used to destroy the managed threads permanently. When the
Abort method is called from the main method, a
ThreadAbortException is thrown.
Windows Forms with Controls
Microsoft introduced a new set of libraries in the .NET Framework with object oriented technology for creating the smart client applications in Windows. Windows Forms doesn't relate to existing technology for creating Windows like MFC, ATL or WTL. Windows Forms support the entire .NET Framework, and several languages share the same set of class libraries with .NET features. For example, MFC developers can get the features for .NET. Microsoft allows developers to mix both MFC and Windows forms into a single project. New MFC classes are used to access the .NET Windows Forms controls.
In our example, Windows Forms access between the multiple threads. The progress bar shows progress with different threads. Each progress bar has a separate button called a
Thread. If we click the individual buttons, the thread starts and runs separately. The
Thread starts in click event.
Thread^ newThread = gcnew Thread(gcnew ParameterizedThreadStart(&ThreadProc3 ));
parameteterizedThreadStart is used to pass the Windows Forms object to the thread function. The
static method calls the safe thread function. If developers want to change the status for Windows Forms control taken by a thread, we should declare a delegate.
delegate void ProgressBarCallback(System::Object ^obj);
This delegate passes a Windows Forms object. We change the status for each progressbar. If you want to invoke methods synchronously, you can call the following code:
static void SafeThread4(System::Object ^obj)
Form1 ^ob = (Form1^) obj;
ProgressBarCallback ^d = gcnew ProgressBarCallback(SafeThread4);
for ( int i = 1; i <= 10; i++ )
Thread::Sleep( 80 );
Managed Threads and Exceptions
In .NET Framework 2.0, CLR handles unhandled exceptions in managed application.
Managed threads throws exception for the following situations:
ThreadAbortException throws when user calls Abort method.
AppDomainUnloadedException throws application domain in which the thread is executing is being unloaded.
- CLR throws when the host processes terminate the thread by throwing internal exception.
When I created the sample application, I tried to access the control class from thread function. But, I got the following exception:
static void ThreadProc1(System::Object ^obj)
Form1 ^ob = (Form1^) obj;
for ( int i = 0; i < 10; i++ )
Thread::Sleep( 0 );
When I execute the above code, I get the following exception:
System.InvalidOperationException was unhandled
Message="Cross-thread operation not valid:
Control 'progressBar1' accessed from a thread other than
the thread it was created on."
It gives the stack trace too.
Each application domain starts with at least a single thread. The
System.Threading.Thread class is used to create one or more number of threads in a managed environment. For a multithreaded application, the CPU switches between threads in a single process. If system uses multiple threads in multiprocessor environment, the thread switch changes between the multiple processors. Microsoft doesn't recommend mixing both managed and unmanaged threads. Managed threads are garbage collected. So, a developer doesn't care about cleaning up resources. So, we don't face the memory leak problem in managed threads. For creating the managed threads using best practices, read this.
- 17th January, 2006: Initial post