限制windows服务中实例的数量
本文关键字:实例 windows 服务 限制 | 更新日期: 2023-09-27 18:00:23
我正在编写一个windows服务,它由计时器启动,每分钟都要做一次耗时的工作。我想限制一次运行的服务实例的数量,比如说100个。我该怎么做?有什么想法吗?
编辑:我想限制计时器启动的线程数。
如果使用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);
}
}
}