Limit Threads count

前端 未结 4 2091
清歌不尽
清歌不尽 2021-01-01 03:22

I have a List with items that I want to download. I use a for Loop to iterate the list.

For each item in this List I start a new Thread that references the item. My

4条回答
  •  北荒
    北荒 (楼主)
    2021-01-01 04:06

    I solved this very problem in .Net 3.5 by creating threads and loading them into a queue. Then I read a thread from the queue, start it, and increment the running thread count. I keep doing this until I hit the upper limit.

    As each thread finishes it invokes a callback method that decrements the running count and signals the queue reader to start more threads. For additional control you can use a dictionary to keep track of running threads, keyed by ManagedThreadId, so you can signal threads to stop early or report progress.

    Sample console app:

    using System;
    using System.Collections.Generic;
    using System.Threading;
    
    namespace ThreadTest
    {
        class Program
        {
            static void Main(string[] args)
            {
                Supervisor supervisor = new Supervisor();
                supervisor.LaunchThreads();
                Console.ReadLine();
                supervisor.KillActiveThreads();
                Console.ReadLine();
            }
    
            public delegate void WorkerCallbackDelegate(int threadIdArg);
            public static object locker = new object();
    
            class Supervisor
            {
                Queue pendingThreads = new Queue();
                Dictionary activeWorkers = new Dictionary();
    
                public void LaunchThreads()
                {
                    for (int i = 0; i < 20; i++)
                    {
                        Worker worker = new Worker();
                        worker.DoneCallBack = new WorkerCallbackDelegate(WorkerCallback);
                        Thread thread = new Thread(worker.DoWork);
                        thread.IsBackground = true;
                        thread.Start();
                        lock (locker)
                        {
                            activeWorkers.Add(thread.ManagedThreadId, worker);
                        }
                    }
                }
    
                public void KillActiveThreads()
                {
                    lock (locker)
                    {
                        foreach (Worker worker in activeWorkers.Values)
                        {
                            worker.StopWork();
                        }
                    }
                }
    
                public void WorkerCallback(int threadIdArg)
                {
                    lock (locker)
                    {
                        activeWorkers.Remove(threadIdArg);
                        if (activeWorkers.Count == 0)
                        {
                            Console.WriteLine("no more active threads");
                        }
                    }
                }
            }
    
            class Worker
            {
                public WorkerCallbackDelegate DoneCallBack { get; set; }
                volatile bool quitEarly;
    
                public void DoWork()
                {
                    quitEarly = false;
                    Console.WriteLine(Thread.CurrentThread.ManagedThreadId.ToString() + " started");
                    DateTime startTime = DateTime.Now;
                    while (!quitEarly && ((DateTime.Now - startTime).TotalSeconds < new Random().Next(1, 10)))
                    {
                        Thread.Sleep(1000);
                    }
                    Console.WriteLine(Thread.CurrentThread.ManagedThreadId.ToString() + " stopped");
                    DoneCallBack(Thread.CurrentThread.ManagedThreadId);
                }
    
                public void StopWork()
                {
                    quitEarly = true;
                }
            }
        }
    }
    

提交回复
热议问题