限制线程数 [英] Limit Threads count

查看:226
本文介绍了限制线程数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个列表,其中包含要下载的项目.我使用for循环对列表进行迭代.

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

对于此列表中的每个项目,我启动一个引用该项目的新线程.我的问题是我想同时限制maxDownload.

For each item in this List I start a new Thread that references the item. My Problem is that I want limit the maxDownload at the same time.

for (int i = downloadList.Count - 1; i >= 0; i--)
{
    downloadItem item = downloadList[i];
    if (item.Status != 1 && item.Status != 2)
    {
        ThreadStart starter = delegate { this.DownloadItem(ref item); };
        Thread t = new Thread(starter);
        t.IsBackground = true;
        t.Name = item.Name;
        t.Priority = ThreadPriority.Normal;
        t.Start();
    }
}

我阅读了一些有关ThreadPool的信息,但是后来我无法引用我的项目.有人能帮我吗?谢谢! :)

I read something about the ThreadPool, but then I can't reference my item. Can someone Help me? Thanks! :)

我对此进行了测试:

ThreadPool.SetMaxThreads(maxDownloads, maxDownloads);
ThreadPool.SetMinThreads(maxDownloads, maxDownloads);
ThreadPool.QueueUserWorkItem(DownloadItem, ref item);

我不知道如何通过该线程引用我的downloadItem...

I don't know how I can reference my downloadItem with this thread.....

推荐答案

我通过创建线程并将它们加载到队列中来解决了.Net 3.5中的这个问题.然后,我从队列中读取一个线程,启动它,并增加正在运行的线程数.我一直这样做,直到达到上限.

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.

每个线程结束时,它会调用一个回调方法,该方法将减少运行计数并发信号通知队列读取器启动更多线程.为了获得更多控制,您可以使用字典来跟踪正在运行的线程(由ManagedThreadId键控),以便向线程发出信号以尽早停止或报告进度.

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.

示例控制台应用程序:

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<Thread> pendingThreads = new Queue<Thread>();
            Dictionary<int, Worker> activeWorkers = new Dictionary<int, Worker>();

            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;
            }
        }
    }
}

这篇关于限制线程数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆