Multi threading- The Killer tool
.NET threading is a powerful tool that can be used by applications that demand high scalability. Without using
Threading namespace, I doubt if we can unleash the real power of .NET platform. All the back end applications like Database servers, Web servers, Queue management systems and the applications like Word, Excel use multi threading.
In .NET, the perfect OO platform threads are also created and accessed as objects.
The main and multiple worker threads model, is used by many applications. In this model a parent thread starts many worker threads based on the service required. All the worker threads do the same work but within a pre-defined context set by the parent. E.g. In a database server application a new worker thread is created whenever a new client is connected. This is an over simplified example and the actual logic is more complex than this.
In this model the worker thread may want to send messages to the main thread to report its progress. The crucial part in this messaging is that the message notifying code should be executed by the Parent thread and not by the worker thread.
This project can be used as a tool to accomplish the above mentioned. This is a Thread pool management system with communication facility enabled. There is a class called
ThreadManager which has the facility for its client to define the number of threads, the method that should be invoked by the worker thread and the method that should be called when notifying the parent thread.
The class implements an
interface that is shown below:
public interface IThreadManager
void SetRunMethod(MethodNoParam Run);
void SetMessageReceiveMethod(MethodWithParam Receive);
void SendMessageToMain(object Message);
- Number of threads to be started is specified in the constructor.
SetRunMethod expects a delegate which points to the code executed by the worker threads when they are started.
SetMessageReceiveMethod is used to specify the message receiving code executed by the
SendMessageToMain is invoked by the worker thread when it wants to send messages to main thread.
_ThreadMgr = new ThreadManager(Convert.ToInt32
MethodNoParam _RunMethod = new
MethodWithParam _ReceiveMethod = new
MethodWithParam are the delegates defined at the global level.
When the worker threads started, they increment the
NoOfRecordsUpdated variable defined in the client till it reaches
RecordsToBeProcessed. Worker threads, after each update, notify the main thread by calling
SendMessageToMain. Any data can be passed on to the
Main thread and the implementation is left to the client. In this case client sends the number of records updated to
private void ThreadMehod()
if (RecordsProcessed >= RecordsToBeProcessed)
The main thread extracts the data passed by the worker threads. In this case it updates the progress bar.
private void CallBackMethod(object State)
The thread which executes this code can be confirmed as Main by un-commenting the second line.
ThreadManager is using a Queue based mechanism for the message delivery.
For other design patterns such as pipeline model where one thread is dependent on the other, we can use the built in functions such as
Join etc. The application defines two delegates which are used by the client. The client which is a Windows form, has methods defined that should be executed by the main and worker threads. The message that is received by the so called
Main thread is passed on to the UI thread using the
Invoke method. All the visual objects that can be created on a Windows form are inherited from the
Control class. The control class exposes
Invoke method which accepts a delegate.
Following shows the
public void DisptachMessage()
while(m_Messages.Count > 0)
Main thread in this example is engaged in dispatching the messages all the time, usage of UI thread for this purpose is discouraged.
private void CallBackMethod(object State)
The message that is received by the
Main thread, which is Records updated in the example, is passed to UI which updates the progress bar.
We can use delegate's
BeginInvoke method, when the asynchronous notification is required and the thread from which it originates is not an issue.