Click here to Skip to main content
13,597,485 members
Click here to Skip to main content
Add your own
alternative version

Stats

28.3K views
538 downloads
22 bookmarked
Posted 6 Apr 2009
Licenced CPOL

Simple mutlithreaded application

, 6 Apr 2009
Rate this:
Please Sign up or sign in to vote.
A simple mutlithreaded application using ThreadPool.

Introduction

During some performance testing phases, you often discover that there is a lack in the software performance, and that the solution is not responding, or is not completing its tasks in an acceptable time. This can be caused due to many issues, some related to the code efficiency, or external dependencies, or the execution flow.

In this article, we will see an approach that can help in resolving performance issues. Multi-threading can be a good solution. Multithreading is a popular programming and execution model that allows multiple threads to exist within the context of a single process. These threads share the process' resources but are able to execute independently. The threaded programming model provides developers with a useful abstraction of concurrent execution. However, perhaps the most interesting application of the technology is when it is applied to a single process to enable parallel execution on a multiprocessor system.

Background

You should be familiar with Microsoft .NET, and multi-threading implementation in C#.

Using the code

In this example, we will look at a simple multi-threaded application. We will use the ThreadPool class and the class will be responsible for creating threads, and queuing requests to be picked up later by the created threads. Alternatively, you can do your own thread creation, assignment, and disposing.

First, we will start by creating a parent thread, and assign the delegate to be called. The Start function is a void function with no parameters that will be called once the main thread is created.

Thread parent = new Thread(new ThreadStart(Start));
parent.Start();

The Start function is responsible for creating the threads and queuing the items in the ThreadPool.

private void Start()
{
    // maximum threads cannot be less than the number of CPUs
    ThreadPool.SetMaxThreads(int.Parse(txtMaxThreads.Text), int.Parse(txtMaxIOThreads.Text));
    ThreadPool.SetMinThreads(int.Parse(txtMinThreads.Text), int.Parse(txtMinIOThreads.Text));

    int requestCount = Convert.ToInt32(txtNumberOfRequest.Text);
    AutoResetEvent[] _waitAllEvents; // Array of objects to wait upon.

    // Create an array of objects to wait upon; we need one per thread
    _waitAllEvents = new AutoResetEvent[requestCount];
    // Populate array of waiting objects, one for each work item
    for (int i = 0; i < requestCount; i++)
    {
        _waitAllEvents[i] = new AutoResetEvent(false);
    }
    for (int rqCounter = 0; rqCounter < requestCount; rqCounter++)
    {
        WaitCallback callBack = new WaitCallback(InternalCommand);
        ThreadPool.QueueUserWorkItem(callBack, 
          new Pair(rqCounter.ToString(), _waitAllEvents[rqCounter]));
    }

    // Wait until all our threads have signaled their wait object is done.
    if (Thread.CurrentThread.GetApartmentState() == ApartmentState.STA)
    {
        // WaitAll for multiple handles on an STA thread is not supported.
        // ...so wait on each handle individually.
        foreach (WaitHandle myWaitHandle in _waitAllEvents)
            WaitHandle.WaitAny(new WaitHandle[] { myWaitHandle });
        System.Diagnostics.EventLog.WriteEntry("Finished Execution " + 
                           "STA Mode - Logs are : \n\n", result);
    }
    else
    {
        WaitHandle.WaitAll(_waitAllEvents);
        MessageBox.Show("Finished Execution MTA Mode - Logs are : \n\n" + result);
    }
}

InternalCommand is where the real execution happens, where you can add, delete, or do anything. After you finish, you have to inform the ThreadPool that you finished execution. And, that is done by setting the AutoResetEvent.

private void InternalCommand(object state)
{
    string threadID = (string)((Pair)state).First;
    lock (result)
    {
        result += "Thread with the thread id ";
        result += threadID;
        result += " was called";
        result += "\n";
    }
    AutoResetEvent autoResetEvent = ((Pair)state).Second as AutoResetEvent;
    // Set our wait item to indicate we are done here.
    autoResetEvent.Set();
}

Example execution flow

This example execution flow can be described as follows:

  1. The ThreadPool will be initialized based on the user input.
  2. Based on the request count, the request event handlers will be created.
  3. All request will be queued into the ThreadPool queue, where the ThreadPool will create working threads to handle the requests.
  4. At the execution function, whenever it finishes execution, the handler will be set.
  5. When all event handlers are set, a message box will be shown.

History

  • Version 1.0.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Wael Al Wirr
Program Manager
Jordan Jordan
Self-motivated, creative and results-driven technology executive who is well versed and experienced in leveraging an end-to-end, holistic vision of business objectives to drive full technology / business alignment.

Skilled in grasping business needs and sudden market demand’s shifts by diving into latest business / technology trends, selecting the best fit business model / technology to create a positive reflection on revenue. His multifaceted approach has enabled him to deliver key solutions across a wide range of disciplines including design, development, UX / UI, Business Intelligence.

Technical Specialties are in .Net, Java, Spring Boot, Maven, MS SQL, Oracle, Postgesql, Redis, Javascript, Bootstrap, Angular 2.

You may also be interested in...

Pro
Pro

Comments and Discussions

 
Generalok article Pin
Donsw11-May-09 8:09
memberDonsw11-May-09 8:09 
GeneralRe: ok article Pin
Wael Al Wirr11-May-09 19:53
memberWael Al Wirr11-May-09 19:53 
Generallock(result) Pin
leeloo9996-Apr-09 21:47
memberleeloo9996-Apr-09 21:47 
GeneralRe: lock(result) Pin
Wael Al Wirr6-Apr-09 22:43
memberWael Al Wirr6-Apr-09 22:43 
AnswerRe: lock(result) Pin
ThaiCoon6-Apr-09 22:57
memberThaiCoon6-Apr-09 22:57 
GeneralRe: lock(result) Pin
Wael Al Wirr6-Apr-09 23:28
memberWael Al Wirr6-Apr-09 23:28 
GeneralRe: lock(result) Pin
ThaiCoon7-Apr-09 0:25
memberThaiCoon7-Apr-09 0:25 
GeneralRe: lock(result) Pin
Wael Al Wirr7-Apr-09 0:34
memberWael Al Wirr7-Apr-09 0:34 
GeneralRe: lock(result) Pin
ThaiCoon7-Apr-09 3:10
memberThaiCoon7-Apr-09 3:10 
GeneralRe: lock(result) Pin
Wael Al Wirr7-Apr-09 3:31
memberWael Al Wirr7-Apr-09 3:31 
GeneralRe: lock(result) Pin
ThaiCoon7-Apr-09 3:55
memberThaiCoon7-Apr-09 3:55 
GeneralRe: lock(result) Pin
Wael Al Wirr7-Apr-09 4:05
memberWael Al Wirr7-Apr-09 4:05 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Cookies | Terms of Use | Mobile
Web03-2016 | 2.8.180621.3 | Last Updated 6 Apr 2009
Article Copyright 2009 by Wael Al Wirr
Everything else Copyright © CodeProject, 1999-2018
Layout: fixed | fluid