ASP.Net核心中的Hangfire:简单的重复作业不会刷新其动态内容

问题描述:

我想在ASP.Net Core 1.1中的web应用程序上实现cron任务。ASP.Net核心中的Hangfire:简单的重复作业不会刷新其动态内容

我决定选择Hangfire库。

为了检查我的安装和配置都工作正常,我只是写了一个很简单的重复性作业,旨在打印当前的日期时间上的控制台输出:

RecurringJob.AddOrUpdate(() => Console.WriteLine($"{DateTime.Now}"), Cron.Minutely); 

奇怪的是,每分钟,它将打印相同的消息,对应于首次打印消息的日期和时间,并且不更新DateTime.Now部件。

如果我访问/迟发型仪表盘,并期待在工作的细节,似乎翻译为静态日期时间输出,因此:

Console.WriteLine("15/09/2017 15:27:21"); 

所以工作似乎是一种“编译”排队时这显然不是我想要做的。

我试图用数据库表中的行计数来替换这个作业。问题是一样的:如果我在作业的两次出现之间添加或删除行,显示的行数不会更新。只有在重新启动Web应用程序时才会更新。

所以你的问题是,Hangfire使用NewtonSoft序列化你发送给作业的参数。当你的程序排队工作时,它获取当前时间,然后在那个时间调用该函数。

尝试将函数移入方法调用。因此,而不是

RecurringJob.AddOrUpdate(() => Console.WriteLine($"{DateTime.Now}"), Cron.Minutely); 

尝试

RecurringJob.AddOrUpdate(() => PrintTime(), Cron.Minutely); 
... 
private static void PrintTime() { 
    Console.WriteLine($"{DateTime.Now}"); 
} 

如果我迟发型的理解是正确的,这只会序列化调用的方法的名称,而不是序列化的时间。

+0

其实你的答案可能会提供相同的输出,另一个原因,但我已经明白了为什么和解决(将张贴答案)。静态类中的静态方法是我的问题。一旦我将我的方法移动到每次执行时立即执行的类,一切都很顺利。对于这个特定的情况,我认为你发现了这个问题。 – kall2sollies

+1

@ kall2sollies根据[快速测试](https://shifty.site/JiBYF),我可以确认它会起作用。 我正在处理的应用程序有几层,但所有的hangfire进程都是通过公共静态类中的公共方法启动的。重要的是,在Enqueue/AddOrUpdate方法中为hangfire提供的信息是发送到方法的快照。在这些方法中发生什么,以及在这些方法中生成的内容是在该方法运行时确定的。 –

+0

我想也许我的第一次尝试是一个陷阱。我的静态类是为了保存ASP.Net项目中Startup类的Configure方法的扩展方法,作业注册在这个扩展方法中,被调用方法在同一个静态类中的另一个静态方法中。无论如何,最重要的是,如果执行得当,它一切正常!感谢您的努力! – kall2sollies

对于我的问题中描述的问题,Stephen Vernyi发现了这个问题:由于Hangfire使用JSON序列化参数,因此第一个日期时间在序列化时被冻结,以便每个后续执行都会提供相同的输出。

但是在写一个方法时一定要小心,正如他所建议的那样。

因为我随意地尝试这一切工作,所有我的测试在静态类中写入静态方法。而这样的实现提供了相同的冻结日期时间问题!

当我决定重构我的实现时,使用Job services,在默认的ASP.Net Core IoC容器中注册,并设置为在每个请求中提供新的服务实例,它不仅解决了冻结输出问题,而且还每个依赖注入遇到的问题。