Search code examples
c#threadpool

Use ThreadPool in C# within a loop and wait for all threads to finish


I have a simple code that looks like this in C#:

using System;
using System.Threading;
using System.Diagnostics;


namespace ThreadPooling
{
    class Program
    {
        static void Main(string[] args)
        {

            Console.WriteLine("Enter the number of calculations to be made:");
            int calculations= Convert.ToInt32(Console.ReadLine());

            Console.WriteLine("Thread Pool Execution");

            for (int i = 1; i <= calculations; i++)
            {
                Console.WriteLine("Staring process " + i + "...");
                ThreadPool.QueueUserWorkItem(new WaitCallback(Process(i)));
            }

            Console.WriteLine("All calculations done.");
            Console.WriteLine("\nPress any key to exit the program...");
            Console.ReadKey();

        }

        static void Process(object callback, int name)
        {
            for (int i = 0; i <= 10; i++)
            {
                Console.WriteLine(i + " is the current number in " +  name);
            }
        }


    }
}

I want main to be able to call Process with Thread Pool and an argument. I then want the program to wait for all threads to finish before telling the user that it is done. How do I do both? It seems I cannot put an argument inside Process, I get: Error CS7036 There is no argument given that corresponds to the required formal parameter 'name' of 'Program.Process(object, int)'

And I am not clear on how to tell C# to wait for all processes with in the loop to finish before it tells the user it is done.


Solution

  • .NET is almost 20 years old, and has several generations of improving APIs in it.

    This is trivial with the newer Task Parallel Library methods. EG

    using System;
    using System.Collections.Generic;
    using System.Threading.Tasks;
    
    namespace ThreadPooling
    {
        class Program
        {
            static void Main(string[] args)
            {
    
                Console.WriteLine("Enter the number of calculations to be made:");
                int calculations = Convert.ToInt32(Console.ReadLine());
    
                var tasks = new List<Task>();
                for (int i = 1; i <= calculations; i++)
                {
                    int processNum = i;
                    Console.WriteLine("Staring process " + processNum + "...");
                    var task = Task.Run(() => Process(processNum));
                    tasks.Add(task);
                }
    
                Task.WaitAll(tasks.ToArray());
                Console.WriteLine("All calculations done.");
                Console.WriteLine("\nPress any key to exit the program...");
                Console.ReadKey();
    
            }
    
            static void Process(int name)
            {
                for (int i = 0; i <= 10; i++)
                {
                    Console.WriteLine(i + " is the current number in " + name);
                }
            }
    
    
        }
    }