.Net最大并发计时器线程

Eul*_*367 7 .net c# multithreading

我正在尝试加载间隔进程的队列.换句话说,我有一个队列,我希望队列中的每个项目都在一个单独的时间间隔上运行.

我的问题是,我似乎无法一次运行超过25个线程.我在64位机器上使用.Net 4.5,其默认最大线程数为32768.

如何使我的应用程序运行尽可能多的并发线程,因为我的机器可以处理?

这是一个示例应用程序,它复制了我的生产代码中的实际问题:

class Program
{
    static void Main(string[] args)
    {
        System.Threading.ThreadPool.SetMaxThreads(200, 200);
        test t = new test();

        t.LoadUrls("http://www.google.com");

        while (1 == 1)
        {
            System.Threading.Thread.Sleep(1000);//refresh every 5 seconds
            Console.WriteLine(System.Diagnostics.Process.GetCurrentProcess().Threads.Count);
        }
    }


    public class test
    {

        public void LoadUrls(string url)
        {
            for (int i = 0; i < 100; i++)
            {
                System.Threading.Timer t = new System.Threading.Timer(new System.Threading.TimerCallback(RunInterval), url, 0, 1000);
                Console.WriteLine("Loaded {0} feeds.", i);
            }
        }
        private static void RunInterval(object state)
        {
            string url = state as string;
            string data = "";

            using (System.Net.WebClient cl = new System.Net.WebClient())
            {
                Console.WriteLine("getting data for " + url);
                data = cl.DownloadString(url);
            }

            //do something with the data

        }
    }
}
Run Code Online (Sandbox Code Playgroud)

理论上,这段代码应在2秒左右后运行198个线程.

顺便说一句,这在我的原型应用程序中运行得很好; 它是在节点中写的.但是,现在我无法让它在c#中正常工作......

答案: 问题实际上是垃圾收集,根本不是线程池问题; 游泳池不仅可以将我正在投掷的所有线程都假脱机.诀窍是使用System.Threading.Timer的单个参数构造函数; 这将使计时器将自己用作信号量,从而避免使用gc.

class Program
{
    static void Main(string[] args)
    {
        for (int i = 0; i < 100; i++)
        {
            test t = new test();
            t.url = "http://www.google.com?" + i;
            System.Threading.Timer ti = new System.Threading.Timer(new System.Threading.TimerCallback(t.RunInterval));
            ti.Change(0, 1000);
        }

        while (1 == 1)
            System.Threading.Thread.Sleep(int.MaxValue);
    }


    public class test
    {
        public string url { get; set; }
        public void RunInterval(object state)
        {
            Console.WriteLine("getting data for " + this.url);
            string data = "";

            using (System.Net.WebClient cl = new System.Net.WebClient())
            {
                data = cl.DownloadString(this.url);
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我不确定为什么你会想要一个计时器被gc收集,但嘿我知道什么.

Hen*_*man 5

如何使我的应用程序运行尽可能多的并发线程,因为我的机器可以处理?

这是错误的做法.每个线程都是昂贵的,创建几百个,你的系统将严重降级.

您的代码使用ThreadPool.池有一个限制线程数的算法.当你增加Sleep()次数时,你可能会看到更多的线程.

更直接的方法是设置ThreadPool.MinThreads.但期望性能降低,而不是更多.