【发布时间】:2015-04-21 21:10:33
【问题描述】:
出于测试原因,我希望能够调整 Quartz.Net 当前认为的时间,因此我不必等待数小时、数天或数周来检查我的代码是否正常工作。
为此,我创建了以下简单函数(它在 F# 中,但可以很容易地用 C# 或其他语言完成):
let SimulateTime = fun () ->
currentTime <- DateTimeOffset.UtcNow
timeDifferenceInSeconds <- (currentTime - lastCheckedTime).TotalSeconds
simulatedTime <- simulatedTime.AddSeconds((timeDifferenceInSeconds *scaleTimeBy))
lastCheckedTime <- currentTime
simulatedTime
currentTime、lastCheckedTime 和simulatedTime 都是DateTimeOffset 类型,而timeDifferenceInSeconds 和scaleTimeBy 都是float 类型。
然后我将 SystemTime.Now 和 SystemTime.UtcNow 更改为使用上述功能,如下所示:
SystemTime.Now <-
Func<DateTimeOffset>(
fun () -> SimulateTime())
SystemTime.UtcNow <-
Func<DateTimeOffset>(
fun () -> SimulateTime())
Mark Seemann 在我的上一个问题中展示了这一点,可以找到here。
现在这主要是可行的,只是似乎较长的函数导致它偏离了相当大的幅度。我的意思是我所有的触发器都会失火。例如,如果我将触发器设置为每小时发生一次,并将 scaleTimeBy 设置为 60.0,以便通过的每一秒都计为一分钟,那么它永远不会真正按时触发。如果我有一个失火策略,那么触发器可以关闭,但它列出的激活时间将迟至半小时标记(因此比本示例中应该慢了整整 30 秒)。
但是我可以这样做:
Console.WriteLine(SimulateTime())
Thread.Sleep(TimeSpan.FromSeconds(60.0))
Console.WriteLine(SimulateTime())
在这个例子中,两次输出到屏幕的时间差正好是一个小时,所以调用看起来不应该比它增加那么多的时间差。
有人对如何解决此问题或处理此问题的更好方法有任何建议吗?
编辑: 所以 SimulateTime 函数的 C# 版本应该是这样的:
public DateTimeOffset SimulateTime() {
currentTime = DateTimeOffset.UtcNow;
double timeDifference = (currentTime - lastCheckedTime).TotalSeconds;
simulatedTime = simulatedTime.AddSeconds(timeDifference * scaleTimeBy);
lastCheckedTime = currentTime
return simulatedTime;}
如果这有助于任何人解决这个问题。
【问题讨论】:
-
虽然我现在对 Quartz.Net 一无所知,但这听起来像是 Quartz.Net 的问题,或者你使用它的方式。我猜想熟悉这个库的 C# 开发人员比 F# 开发人员要多得多,因此如果您在 C# 中重现该问题,并在此处发布 C# 代码而不是 F#...
-
以上是不是更有帮助?
-
还决定看看是否可以通过在调用模拟时间函数时将 timeDifference 与当前时间一起打印来解决问题。看起来 Quartz.net 通常会同时进行 5 次调用,然后在进行另一组调用之前等待。在测试时,这个等待时间似乎在大约 20 秒和大约 0.001 秒之间交替(主要问题中提到的 30 秒似乎更像是一个不寻常的异常值,尽管 20 秒仍然很糟糕),有人知道这是为什么吗?
-
因此,通过挖掘 Quartz.net 的源代码,我在 SchedulerThread 中发现了一个名为 idleWaitTime 的变量,我猜它是负责的。有没有人能够确认或过去处理过它?
-
是的,它似乎与 idleWaitTime 有关,而且这个问题似乎通常只在与服务器打交道时出现。它可能是可配置的,我现在正试图弄清楚如何做到这一点。如果有人确实知道如何更改它(最好以一种可以根据 ScaleTimeBy 动态更改它的方式)让我知道,因为它会为我节省一些工作。
标签: c# f# quartz.net c#-to-f# quartz.net-2.0