Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use ThreadPool class

Tags:

c#

namespace ThPool
{
    class Program
    {
        private static long val = 0;
        private static string obj = string.Empty;

        static void Main(string[] args)
        {
            Thread objThread1 = new Thread(new ThreadStart(IncrementValue));
            objThread1.Start();
            Thread objThread2 = new Thread(new ThreadStart(IncrementValue));
            objThread2.Start();
            objThread1.Join();
            objThread2.Join();

            Console.WriteLine("val=" + val + " however it should be " + (10000000 + 10000000));

            Console.ReadLine();
        }

        private static void IncrementValue()
        {
            for (int i = 0; i < 10000000; i++)
            {
                Monitor.Enter(obj);
                val++;
                Monitor.Exit(obj);
            }
        }
    }
}

How do I use ThreadPool class in replacement of thread & monitor?

like image 951
huda Avatar asked Feb 01 '09 12:02

huda


People also ask

How does a ThreadPool work?

A thread pool reuses previously created threads to execute current tasks and offers a solution to the problem of thread cycle overhead and resource thrashing. Since the thread is already existing when the request arrives, the delay introduced by thread creation is eliminated, making the application more responsive.

What is the use of ThreadPool in C#?

Thread pool in C# is a collection of threads. It is used to perform tasks in the background. When a thread completes a task, it is sent to the queue wherein all the waiting threads are present. This is done so that it can be reused.

What is a ThreadPool in Java?

Java Thread pool represents a group of worker threads that are waiting for the job and reused many times. In the case of a thread pool, a group of fixed-size threads is created. A thread from the thread pool is pulled out and assigned a job by the service provider.

How do you wait for ThreadPool to finish?

You can wait for a task to finish in a ThreadPoolExecutor by calling the wait() module function.


3 Answers

There are a couple of ways to use the thread pool. For your task, you should look at the following.

  • If you just need a task to run the easiest way is to use QueueUserWorkItem, which simply takes a delegate to run. The disadvantage is that you have little control over the job. The delegate can't return a value, and you don't know when the run is completed.
  • If you want a little more control, you can use the BeginInvoke/EndInvoke interface of delegates. This schedules the code to run on a thread pool thread. You can query the status via the IAsyncResult handle returned by BeginInvoke, and you can get the result (as well as any exception on the worker thread) via EndInvoke.

To use the Enter/Exit on Monitor properly, you have to make sure that Exit is always called. Therefore you should place your Exit call in a finally block.

However, if you don't need to supply a timeout value for Enter, you would be much better off just using the lock keyword, which compiles into a proper set of Enter and Exit calls.

like image 196
Brian Rasmussen Avatar answered Oct 07 '22 00:10

Brian Rasmussen


EventWaitHandle[] waitHandles = new EventWaitHandle[2];


for(int i = 0; i < 2; i++)
{
    waitHandles[i] = new AutoResetEvent(false);
    ThreadPool.QueueUserWorkItem(state =>
    {
        EventWaitHandle handle = state as EventWaitHandle;
        for(int j = 0; j < 10000000; j++)
        {
            Interlocked.Increment(ref val); //instead of Monitor
        }
        handle.Set();
    }, waitHandles[i]);
}

WaitHandle.WaitAll(waitHandles);
Console.WriteLine("val=" + val + " however it should be " + (10000000 + 10000000));
like image 32
Pablo Retyk Avatar answered Oct 07 '22 00:10

Pablo Retyk


You should look into ThreadPool.QueueUserWorkItem(). It takes a delegate that is run on the threadpool thread, passing in a state object.

i.e.

string fullname = "Neil Barnwell";
ThreadPool.QueueUserWorkItem(state =>
{
    Console.WriteLine("Hello, " + (string)state);
}, fullname);

Don't be confused by Control.BeginInvoke(). This will marshal the call to the thread that created the control, to prevent the issue where cross-thread calls update Controls. If you want simple multi-threading on a Windows form, then look into the BackgroundWorker.

like image 33
Neil Barnwell Avatar answered Oct 06 '22 23:10

Neil Barnwell