Windows服务定期生成一个最大的线程

我已经阅读了数百页并且现在使用了这么多样本,我完全感到困惑。 大多数示例似乎针对以下内容:

  • 让一个计时器产生一个新的线程,它将完成一些工作,具有无限的线程
  • 产生特定数量的线程,每个线程都有一个执行某些操作的计时器
  • 做一些工作

我想要完成的是:

  • 让计时器运行以定期生成一个线程
  • 此线程可能需要或可能不会超过计时器滴答
  • 限制可以生成多少个线程
  • 线程完成后,将线程返回,以便再次使用
  • 每个线程中的工作是彼此独立的,并且可以在异步中运行(这并不重要)

作为类比,我希望我的应用程序像一艘有10条钓鱼线的渔船一样工作。 在开始时你输出一个(按需),然后另一个,依此类推。 在任何给定时间,水中可以有0到10条钓鱼线。 每当捕获一条鱼时,线路就会被拉起并准备好再次施放(如果需要的话)。

听起来我应该使用ThreadPool? 我还认为为了保持简单,我应该生成一个线程,如果没有工作,立即返回它(即从某个表中选择count,如果count为0,则返回线程),而不是试图聪明地弄清楚如果我需要产卵,因为有需要。

一般情况下,当系统安静时,它将不断产生一个线程,看到没有工作然后返回,但在繁忙时间,线程可能会被使用到极限,系统将继续失败生成新线程,直到完成后再次返回一个或多个线程。

我已经尝试过System.Threading和Semaphores以及WaitHandles,但这一切都让人非常困惑。 我没有代码可以显示,因为我继续删除并重新开始,采用不同的方法。 任何帮助,将不胜感激。

我在C#2010开发。

在使用线程池和计时器之前,我已经得到了类似的东西:

public class MaxThreadCountWorker : IDisposable { private readonly int _maxThreadCount; private readonly int _tickIntervalMilliseconds; private readonly Action _periodicWork; private readonly System.Threading.Timer _timer; private int _currentActiveCount; public MaxThreadCountWorker(int maxThreadCount, int tickIntervalMilliseconds, Action periodicWork) { _maxThreadCount = maxThreadCount; _tickIntervalMilliseconds = tickIntervalMilliseconds; _periodicWork = periodicWork; _timer = new System.Threading.Timer(_ => OnTick(), null, Timeout.Infinite, Timeout.Infinite); _currentActiveCount = 0; } public void Start() { _timer.Change(0, _tickIntervalMilliseconds); } public void Stop() { _timer.Change(Timeout.Infinite, Timeout.Infinite); } private void DoWork() { try { _periodicWork.Invoke(); } finally { Interlocked.Decrement(ref _currentActiveCount); } } private void OnTick() { _timer.Change(Timeout.Infinite, Timeout.Infinite); try { if (_currentActiveCount >= _maxThreadCount) return; Interlocked.Increment(ref _currentActiveCount); ThreadPool.QueueUserWorkItem(_ => DoWork()); } finally { _timer.Change(_tickIntervalMilliseconds, _tickIntervalMilliseconds); } } public void Dispose() { _timer.Dispose(); } } class Program { private static object _lockObject = new object(); private static int _runningTasks = 0; private static void PrintToConsole() { lock (_lockObject) { _runningTasks += 1; } try { Console.WriteLine("Starting work. Total active: {0}", _runningTasks); var r = new Random(); System.Threading.Thread.Sleep(r.Next(3500)); } finally { lock (_lockObject) { _runningTasks -= 1; } } } static void Main(string[] args) { using (var w = new MaxThreadCountWorker(3, 150, PrintToConsole)) { w.Start(); Console.ReadKey(); } } } 

我认为你应该使用内置的ThreadPool而不是发明自己的。 您在问题中描述的情况是处理属性实现的线程池所需的复杂性的一部分。 而不是自己这样做,我认为你可以通过使用现有的来获得很多(除非你这样做是为了了解线程池的工作原理)。

要使用内置线程池,您应该在事件处理程序中调用TreadPool.QueueUserWorkItem()以获取计时器TreadPool.QueueUserWorkItem()

Threadpool是你的答案。 真正的问题是你是否需要来自线程的任何反馈。 如果不是这样的话,那么线程池中的线程就会被激活,这将管理线程数量的限制。 然后继续,将计时器滴答作为睡眠过程处理。

如果你需要任何东西,那么处理就会变得复杂得多。

是的,启动线程,让它决定是否有任何工作要做。 在这种情况下,这是完全合理的,检查是否需要取消任何东西都没有价值。