【问题标题】:Multithreading Task Library, Threading.Timer or threads?多线程任务库,Threading.Timer 还是线程?
【发布时间】:2011-09-29 10:19:24
【问题描述】:

您好,我们正在构建一个可以注册计划任务的应用程序。

每个任务都有一个应该执行的时间间隔 每个任务都应该有一个超时 任务的数量可以是无限的,但在正常情况下约为 100。

所以我们有一个需要间隔执行的任务列表,哪些是最好的解决方案?

我已经研究过为每个任务提供计时器,当计时器结束时,工作将开始,另一个计时器会跟踪超时,因此如果达到超时,另一个计时器会停止线程。

这感觉像是我们在过度使用计时器?或者它可以工作吗?

另一种解决方案是为每个任务使用计时器,但是当时间过去时,我们会将任务放在一个队列中,该队列将由一些执行工作的线程读取?

我应该寻找其他任何好的解决方案吗?

【问题讨论】:

  • 主题听起来像 .net。如果需要,删除标签。
  • 我再次删除了 .net 标签。如果 OP 不是在寻找 .NET 解决方案,那只会给他带来大量无用的答案。 @NPehrsson,请添加一些关于这是什么平台/语言的信息。

标签: multithreading .net-4.0 scheduled-tasks


【解决方案1】:

没有太多信息,但看起来你也可以考虑 RX - check more at MSDN.com

您可以将您的任务视为应以某种方式组合(计划)的生成事件。因此,您可以执行以下操作:

  • 使用Observable.GenerateWithDisposable 和您自己的Scheduler 生成可取消的任务 - 在Rx 101 Sample 上查看更多信息
  • 使用Observable.Delay 延迟任务
  • 使用'Observable.Timeout 等待任务
  • 以任何更好的方式编写任务

您可以再次在上述指定链接中查看更多信息。

【讨论】:

  • 似乎是一个解决方案,我想知道它在下面是如何工作的,是否适合使用它来处理数千个任务。
  • 只有测试/原型设计才能判断它是否适合您。但是 Rx 是基于 TPL 来处理并发的,所以它应该可以保证相当好的性能指标。
【解决方案2】:

我之前做过类似的事情,其中​​有很多需要定期启动和超时的套接字对象。我使用了一个带有“OnStart”和“OnTimeout”事件的“TimedAction”类(由此派生的套接字类等),以及一个处理所有定时操作的线程。该线程维护了一个 TimedAction 实例列表,该列表按所需的下一个操作的滴答时间排序(增量队列)。通过将 TimedAction 对象排队到线程输入队列中,将它们添加到列表中。线程在此输入队列上等待超时(这是 Windows,因此在管理队列的信号量的句柄上为“WaitForSingleObject”),设置为列表中第一项的“需要下一个操作”滴答计数。如果队列等待超时,则调用列表中第一个项目的相关操作事件并将该项目从列表中删除 - 然后下一个队列等待将由新的“列表中的第一个项目”设置,其中包含新的“最近行动时间”。如果一个新的 TimedAction 到达队列,线程计算它的超时滴答时间,(GetTickCount + 对象的毫秒间隔),并将其插入到正确位置的排序列表中,(是的,这有时意味着移动很多对象列出列表以腾出空间)。

超时处理程序线程调用的事件不能采取任何冗长的操作,以防止延迟处理其他超时。通常,事件处理程序会设置一些状态枚举,向一些同步对象发出信号或将 TimedAction 排队到其他一些 P-C 队列或 IO 完成端口。

这有意义吗?它运行良好,在我的服务器中以合理及时和有效的方式处理了数千个定时操作。

我计划进行的一项改进是使用具有一组受限超时间隔的多个列表。我的系统中只使用了三个 const 超时间隔,所以我可以使用三个列表,每个间隔一个。这意味着列表不需要显式排序 - 新的 TimedActions 将始终位于其列表的末尾。这将消除在列表中间昂贵的对象插入。我从来没有这样做过,因为我的第一个设计运行良好,而且我还有很多其他错误要修复:(

两件事:

小心 32 位 tickCount 翻转。

您需要在队列超时块中设置一个循环 - 列表中的项目可能具有完全相同或几乎相同的超时滴答计数。一旦发生队列超时,您需要从列表中删除并触发每个对象的事件,直到新计算的超时时间>0。我对这个犯规了。具有相同超时滴答计数的两个对象到达列表的头部。一个触发了它的事件,但系统滴答计数已经移动,因此下一个对象的计算超时滴答为 -1:INFINITE!我的服务器停止正常工作并最终锁定:(

Rgds, 马丁

【讨论】:

    【解决方案3】:

    您应该查看Quartz.NET

    Quartz.NET 是一个功能齐全、开放的 源作业调度系统,可以 从最小的应用程序到大型应用程序都可以使用 扩展企业系统。

    我相信您需要自己实现超时要求,但安排任务所需的所有管道都可以由 Quartz.NET 处理。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-09-02
      • 2018-08-16
      • 1970-01-01
      • 2021-12-06
      • 2014-10-12
      • 2021-02-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多