您可以尝试以下几件事:
1)如果没有大量任务,则将每个任务线程化并运行'while(true){Sleep(requiredIinterval);task()};' 环形。降低运行低优先级任务的线程的优先级,以便它们被高优先级任务抢占。
好处:这个简单的解决方案很容易尝试,可能会满足您的要求。任何任务的多个副本都不可能运行。
缺点:每个任务所花费的时间被添加到 const 间隔中,因此延长了任务之间的时间。对于数千个任务来说,这不是一个好的解决方案。
2) 同上,但在任务前读取wall-time获取开始时间,任务后读取wall-time获取结束时间。如果 (requiredIinterval-(end-start)) 为正,则转换为 ms 并在该间隔内休眠。
好处:每个任务所花费的时间不会影响超时,除非它比所需的间隔长。任何任务的多个副本都不可能运行。
缺点:对于数千个任务来说,这不是一个好的解决方案。
3) 实现一个增量排序的优先级排队系统。一种方法是为每个优先级使用一个自定义线程池类,再使用一个“timerThread”来运行任务的增量队列。timerThread 类包含 deltaQueue——一个按超时时间排序的任务集合和一个用于任务的“inputQueue”——一个普通的并发队列。timerThread 等待信号量,超时设置为 deltaQueue 头部任务的超时时间,如果等待超时,它会删除任务,将其发送到适合其优先级的线程池,然后返回,在 deltaQueue 的新头部获取任务的超时时间,并再次等待信号量。当任何线程池完成任务时,它会将完成的任务排队到 timerThread inputQueue 并发出信号量。
好处:每个任务所花费的时间不会影响超时,除非它比所需的间隔长。任何任务的多个副本都不可能运行。许多“超时任务”的良好解决方案。这些任务只是在 deltaQueue、threadPools 和 inputQueue 中循环,所以很少有 GC 会搞砸时间。
缺点:与其他解决方案相比复杂性。不确定 C# 线程池类是否允许设置池线程优先级 - 您可能必须通过将 blockingCollection 传递给许多显式线程实例来创建自己的线程池类。
4)我还没有想到的所有其他好的解决方案。