How to run number of processes in bunches of thread without using threadPool & used EventWaitHandler for Handling

StackOverflow https://stackoverflow.com/questions/16851936

Question

  class Process
{
    static void Main(string[] args)
    {
        int threads = 0;
        int processes = 0;
        Console.WriteLine("Total number of processes:");
        processes = Convert.ToInt32(Console.ReadLine());
        Console.WriteLine("Enter number of parallel threads:");
        threads = Convert.ToInt32(Console.ReadLine());

        ManualResetEvent[] events = new ManualResetEvent[threads];

        int k = 0, innercount = 0;           
        //----running in bunches
        do
        {
            for (int l = 0; l < threads; l++)
            {
                if (k < threads)
                {
                    events[l] = new ManualResetEvent(false);
                    Runner r = new Runner(events[l], innercount);
                    new Thread(new ThreadStart(r.Run)).Start();
                    Console.WriteLine("running start...{0}", innercount);
                    k++;
                    innercount++;
                }
            }
            WaitHandle.WaitAny(events);
            k--;
            Console.WriteLine("Decrement counter...{0}", k);
        }
        while (innercount < processes);

        WaitHandle.WaitAll(events);

        Console.WriteLine("All finished!");

        Console.ReadLine();

    }
}
 class Runner
{
    static readonly object rngLock = new object();
    static Random rng = new Random();

    ManualResetEvent ev;
    int id;

    internal Runner(ManualResetEvent ev, int id)
    {
        this.ev = ev;
        this.id = id;
    }

    internal void Run()
    {

            int sleepTime;
            lock (rngLock)
            {
                sleepTime = rng.Next(2000);
            }
            Thread.Sleep(sleepTime);
            Console.WriteLine("Thread Runner {0}",
                               id);
            if (ev.Set())
            {
                Console.WriteLine("release thread...{0}", id);
            }
    }
}

I have to run multiple threads.If one thread is finishes then start another thread.Problem is that its started all process at the same time.(Seems that this condition not working fine WaitHandle.WaitAny(events);)

1:If 20 threads are running then 21st will be started when One thread releases from 20s thread.

2: Without using threadpool can it be done using EventWaitHandler.

Was it helpful?

Solution

You could do something with PLinq and WithDegreeOfParallelism.

WithDegreeOfParallelism will limit the number of threads that simultaneously run.

The following example shows how to use Plinq to run a number of workers with limited parallelism passing a different object to each worker.

It assumes that you start off with a sequence of objects, and you want to pass each of those objects to a worker method:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;

namespace Demo
{
    class DataForWorker
    {
        public int ID;
        public string Value;
    };

    class Program
    {
        Random rng = new Random();
        int numberOfThreadsRunning;

        void Run()
        {
            int maxThreads = 8;

            IEnumerable<DataForWorker> dataForWorkers = getDataForWorkers();

            dataForWorkers
                .AsParallel()
                .WithDegreeOfParallelism(maxThreads)
                .ForAll(worker);
        }

        IEnumerable<DataForWorker> getDataForWorkers()
        {
            // Just return some dummy data.

            int numberOfDataItems = 30;

            return Enumerable.Range(1, numberOfDataItems).Select
            (
                n => new DataForWorker
                {
                    ID = n,
                    Value = n.ToString()
                }
            );
        }

        void worker(DataForWorker data)
        {
            int n = Interlocked.Increment(ref numberOfThreadsRunning);
            Console.WriteLine("Thread " + data.ID + " is starting. #threads now = " + n);
            Thread.Sleep(rng.Next(1000, 2000));
            Console.WriteLine("Thread " + data.ID + " is stopping.");
            Interlocked.Decrement(ref numberOfThreadsRunning);
        }

        static void Main()
        {
            new Program().Run();
        }
    }
}

OTHER TIPS

Try using Semaphore to control the release of your threads. Look at the example there. But I wonder why you cannot use ThreadPool to accomplish this?

The count on a semaphore is decremented each time a thread enters the semaphore, and incremented when a thread releases the semaphore. When the count is zero, subsequent requests block until other threads release the semaphore. When all threads have released the semaphore, the count is at the maximum value specified when the semaphore was created.

This way, once a thread released a slot in your semaphore, another thread can take up that slot and run.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top