我有一个应用程序,需要从不同的模块执行很多操作,每秒定期执行一次。 这些行动彼此无关。 有些动作并不那么重要,可以超过1秒。期限为几秒钟,但对于另一个 行动它们在1秒内执行是非常重要的。句点(延迟最多400毫秒)。
到目前为止,我的开发方法是给每个动作一个计时器,但现在我已达到40个计时器,我注意到了 每个动作的延迟都很长。
我的问题是,鉴于上面提到的限制,我的应用程序的最佳方法是什么。 何时使用线程,何时使用定时器甚至任务? 也许我甚至在错误的框架上,.Net无法处理这种情况?!
感谢您的帮助, 哈达
P.S:也许值得一提的是,从一开始就知道所有的任务,这意味着我的问题不是 动态添加任务,但决定开发应用程序的方法。答案 0 :(得分:0)
您可以尝试一些事项:
1)如果没有大量的任务,请关闭每个任务并运行'while(true){Sleep(requiredIinterval); task()};'环。降低运行优先级较低的任务的线程的优先级,以便它们被优先级较高的任务抢占。
好处:这个简单的解决方案非常容易尝试,可以满足您的要求。任何任务的多个副本都无法运行。
下行:每个任务所花费的时间被添加到const间隔中,因此延长了任务之间的时间。数千个任务不是一个好的解决方案。
2)与上述相同,但通过阅读任务前的壁挂时间获取开始时间,通过阅读任务后的壁挂时间获取结束时间。如果(requiredIinterval-(end-start))为正,则转换为ms并在该时间间隔内休眠。
上行:除非超过所需的时间间隔,否则每项任务所用的时间不会影响超时。任何任务的多个副本都无法运行。
下行:对于成千上万的任务来说,这不是一个好的解决方案。
3)实现增量排序的优先级排队系统。一种方法是使用每个优先级的自定义线程池类,再使用一个“timerThread”来运行任务的增量队列。 timerThread类包含deltaQueue - 由timeout-time排序的任务集合和用于任务的'inputQueue' - 简单的concurrentQueue。 timerThread等待一个信号量,其超时设置为deltaQueue头部任务的超时时间,如果等待超时,则删除任务,将其发送到适合其优先级的线程池,然后再返回,获取deltaQueue新头的任务的超时时间,并再次等待信号量。当任何线程池完成任务时,它将完成的任务排队到timerThread inputQueue并发信号通知信号量。然后,timerThread被唤醒,并且由于等待返回true,它将获得返回的任务并将其重新插入deltaQueue,以便重新启动其“间隔”。
上行:除非超过所需的时间间隔,否则每项任务所用的时间不会影响超时。任何任务的多个副本都无法运行。许多“超时任务”的良好解决方案。这些任务只围绕deltaQueue,threadPools和inputQueue循环,所以很少有GC来搞定时间。
下行:与其他解决方案相比的复杂性。不确定C#threadpool类是否允许设置池化线程优先级 - 您可能必须通过将blockingCollection传递给多个显式线程实例来创建自己的线程池类。
4)我还没有想到的所有其他好的解决方案。