限制windows服务中实例的数量

本文关键字:实例 windows 服务 限制 | 更新日期: 2023-09-27 18:00:23

我正在编写一个windows服务,它由计时器启动,每分钟都要做一次耗时的工作。我想限制一次运行的服务实例的数量,比如说100个。我该怎么做?有什么想法吗?

编辑:我想限制计时器启动的线程数。

限制windows服务中实例的数量

如果使用System.Threading.ThreadPool,有一个名为SetMaxThreads的函数可以控制并发运行线程的最大数量。此外,请注意该页面上关于更改并发线程数的注释。

这听起来像是一个非常糟糕的设计——而且占用了内存/cpu。我不确定我是否理解你说的100个windows服务是什么意思——因为一个服务就是一个服务。至少在拥有独特服务的意义上是这样。你是否通过任务管理器启动了100个隐藏在后台运行的应用程序?如果是这样的话,您可以创建一个真正的windows服务,并在该服务中设置逻辑来控制应用程序的流(以及运行代码的多个实例的执行),从而使其变得更好。

例如,您可以有一个带有一个主线程的windows服务,该服务将休眠n秒,然后执行。主线程唤醒后,它将负责旋转出新的线程。例如,您可以使用线程池,而可以控制活动线程的数量。主线程将检查线程池,以确定它是否已达到容量,如果有效,则派生一个新线程。

Main Service Thread
 > Sleep n. seconds
   > ThreadPool < 100?
     > New Thread

这段代码演示了您需要什么。

只需使用SemaphoreSlim(与Semaphore相同,性能更好)对象即可。

把信号量想象成一个计数器。每等一次,计数器就会下降一个数字。在操作结束时需要释放它。

当计数器为0时,无法获取Semaphore。

关于线程池的建议,我认为这不是一个好主意,因为线程池在应用程序的许多部分都使用,而不仅仅是这个部分。

class Program
    {
        private static SemaphoreSlim threadsSemaphore = new SemaphoreSlim(5, 5);
        static void Main(string[] args)
        {
            Timer timer = new Timer(DoSomeWork, null, 0, 100);
            Console.ReadKey();
        }
        private static void DoSomeWork(object state)
        {
            if (threadsSemaphore.Wait(TimeSpan.FromSeconds(1)))
            {
                try
                {
                    Console.WriteLine("Doing work ...");
                    Thread.Sleep(1000);
                }
                finally
                {
                    threadsSemaphore.Release();
                }
            }
            else
            {
                Console.WriteLine("Skipping work", threadsSemaphore.CurrentCount);
            }

        }
    }