繁体   English   中英

c#控制线程池。 同时运行的线程数量超过预期

[英]c# Controlled Thread Pooling. More threads are running simultaneously than expected

线程池和关键部分的第一个计时器。 我正在尝试管理在任何给定时间处于活动状态的线程数。 MyThreadPool类管理线程计数和活动线程。 MyUsefulWork具有线程可以访问的平方方法。 主要方法使用ThreadPool.QueueUserWorkItem将工作排队。

我正在使用ManualResetEvent类方法Set()和WaitOne()尝试将线程限制为最大数量(MyThreadPool.MaxThreads),在此示例中为三个。 但是显然我做错了,因为我的ActiveThreads计数已经超过了MaxThreads的18(在输出中显示为“ Increment:number”或“ Decreement:number”)。 而且,活动线程在锁内递增,因此如果线程正在等待,则活动线程不会递增。

因此,如果任何人都可以指出我做错了什么,那将会有很大的帮助。 谢谢。

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

namespace ThreadingDemo
{
    class MyUsefulWork
    {
        public void Square(object number)
        {
            try
            {
                Console.WriteLine("Thread: {0} Square of {1} is {2}", Thread.CurrentThread.GetHashCode(), number, Math.Pow(Convert.ToDouble(number), 2));
                Thread.Sleep(2000);
                Console.WriteLine("Thread for {0} woke up", number);
            }
            catch { }
            finally
            {
                MyThreadPool.ThreadFinishedWork();
            }
        }
    }

    public static class MyThreadPool
    {
        private static int ActiveThreads { get; set; }
        private static int MaxThreads { get; set; }
        public static ManualResetEvent Mre { get; set; }
        public static Object IncrementLock { get; set; }
        public static Object DecreementLock { get; set; }

        public static void SetMaxThreads(int maxThreads)
        {
            MaxThreads = maxThreads;
        }
        public static int GetMaxThreads()
        {
            return MaxThreads;
        }
        public static void ThreadStartedWork()
        {
            SetWait();
        }
        public static void ThreadFinishedWork()
        {
            ActiveThreads--;
            ReleaseWait();
        }
        private static void SetWait()
        {
            lock (IncrementLock)
            {
                ActiveThreads++;
                Console.WriteLine("Increment: {0}", ActiveThreads);
                if (ActiveThreads >= MaxThreads)
                    Mre.WaitOne(Timeout.Infinite, true);
            }
        }
        private static void ReleaseWait()
        {
            lock (DecreementLock)
            {
                Console.WriteLine("Decreement: {0}", ActiveThreads);
                if (ActiveThreads < MaxThreads)
                    Mre.Set();
            }
        }
    }

    class Program
    {
        public static int Main(string[] args)
        {
            var myUsefulWork = new MyUsefulWork();
            var inputs = new List<string>();

            MyThreadPool.Mre = new ManualResetEvent(false);
            MyThreadPool.IncrementLock = new object();
            MyThreadPool.DecreementLock = new object();
            MyThreadPool.SetMaxThreads(3);

            for (var i = 1; i <= 20; i++)
                inputs.Add(i.ToString());

            for (int iItem = 1; iItem <= 20; iItem++)
            {
                Console.WriteLine("Queue to Thread Pool {0}", iItem);
                MyThreadPool.ThreadStartedWork();
                ThreadPool.QueueUserWorkItem(new WaitCallback(myUsefulWork.Square), iItem.ToString());
            }
            Console.ReadKey();
            return 0;
        }
    }       
}

输出如下。

Queue to Thread Pool 1
Increment: 1
Queue to Thread Pool 2
Increment: 2
Queue to Thread Pool 3
Increment: 3
Thread: 6 Square of 1 is 1
Thread: 11 Square of 2 is 4
Thread for 1 woke up
Decreement: 2
Queue to Thread Pool 4
Increment: 3
Thread: 12 Square of 3 is 9
Queue to Thread Pool 5
Increment: 4
Queue to Thread Pool 6
Increment: 5
Queue to Thread Pool 7
Increment: 6
Queue to Thread Pool 8
Increment: 7
Thread: 6 Square of 4 is 16
Queue to Thread Pool 9
Increment: 8
Queue to Thread Pool 10
Increment: 9
Queue to Thread Pool 11
Increment: 10
Queue to Thread Pool 12
Increment: 11
Queue to Thread Pool 13
Increment: 12
Queue to Thread Pool 14
Increment: 13
Thread for 2 woke up
Decreement: 12
Thread: 11 Square of 5 is 25
Queue to Thread Pool 15
Increment: 13
Queue to Thread Pool 16
Increment: 14
Queue to Thread Pool 17
Increment: 15
Queue to Thread Pool 18
Increment: 16
Queue to Thread Pool 19
Increment: 17
Queue to Thread Pool 20
Increment: 18
Thread: 13 Square of 6 is 36
Thread: 14 Square of 7 is 49
Thread for 3 woke up
Decreement: 17
Thread for 4 woke up
Decreement: 16
Thread: 6 Square of 9 is 81
Thread: 12 Square of 8 is 64
Thread for 5 woke up
Decreement: 15
Thread: 11 Square of 10 is 100
Thread: 15 Square of 11 is 121
Thread for 6 woke up
Decreement: 14
Thread: 13 Square of 12 is 144
Thread for 7 woke up
Decreement: 13
Thread: 14 Square of 13 is 169
Thread for 9 woke up
Decreement: 12
Thread: 6 Square of 14 is 196
Thread for 8 woke up
Decreement: 11
Thread: 12 Square of 15 is 225
Thread for 10 woke up
Decreement: 10
Thread: 11 Square of 16 is 256
Thread for 11 woke up
Decreement: 9
Thread: 15 Square of 17 is 289
Thread for 12 woke up
Decreement: 8
Thread: 13 Square of 18 is 324
Thread for 13 woke up
Decreement: 7
Thread: 14 Square of 19 is 361
Thread for 14 woke up
Decreement: 6
Thread: 6 Square of 20 is 400
Thread for 15 woke up
Decreement: 5
Thread for 16 woke up
Decreement: 4
Thread for 17 woke up
Decreement: 3
Thread for 18 woke up
Decreement: 2
Thread for 19 woke up
Decreement: 1
Thread for 20 woke up
Decreement: 0

您忘记了Reset() ManualResetEvent ,它始终保持设置状态。

您可能要使用AutoResetEvent而不是ManualResetEvent ,请参见此处

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM