简体   繁体   English

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

[英]Hangfire in ASP.Net Core : simple recurring job does not refresh its dynamic content

I am trying to implement cron task on a web application in ASP.Net Core 1.1. 我正在尝试在ASP.Net Core 1.1中的Web应用程序上实现cron任务。

I decided to choose the Hangfire library. 我决定选择Hangfire库。

In order to check if my installation and configuration were working fine, I just wrote a very simple recurring job, aimed to print the current DateTime on the console output : 为了检查我的安装和配置是否正常,我写了一个非常简单的重复作业,旨在在控制台输出上打印当前的DateTime:

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

The weird thing is that every minute, it prints the same message , corresponding to the date and time of the first time the message was printed, and not updating the DateTime.Now part. 奇怪的是,它每分钟都会打印相同的消息 ,对应于第一次打印消息的日期和时间,而不更新DateTime.Now部分。

If I access the /Hangfire dashboard, and look at the job details, it appears translated as static datetime output, as such : 如果我访问/ Hangfire仪表板,并查看作业详细信息,它将显示为静态日期时间输出,如下所示:

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

So the job seems to be kind of 'compiled' when enqueued and this is obviously not what I intended to do. 因此,该工作入队后似乎有点“被编译”,这显然不是我想要做的。

I tried to replace this job by a job counting rows on a database table. 我试图通过对数据库表上的行进行计数的作业来代替此作业。 And the problem is the same : if I add or remove rows between two occurences of the job, the row count displayed is not updated. 问题是相同的:如果我在两次作业之间添加或删除行,则显示的行数不会更新。 Update only occurs if I restart the web application. 仅当我重新启动Web应用程序时才会发生更新。

So your problem is that Hangfire serializes the arguments you send to the job using NewtonSoft. 因此,您的问题是Hangfire使用NewtonSoft序列化了发送给作业的参数。 When your program enqueues the job, it gets the current time, and then will call that function with that time. 当程序将作业排入队列时,它将获得当前时间,然后在该时间调用该函数。

Try moving the function into a method call. 尝试将函数移到方法调用中。 So instead of 所以代替

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

Try 尝试

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

If my understanding of Hangfire is correct, this will only serialize the name of the method to call, but not serialize the time. 如果我对Hangfire的理解是正确的,那么这只会序列化要调用的方法的名称,而不会序列化时间。

For the issue described in my question, Stephen Vernyi has spotted the issue : since Hangfire serializes parameters in JSON, the first datetime was frozen when serialized, so that each subsequent execution would provide the same output. 对于我的问题中描述的问题,Stephen Vernyi已经发现了该问题:由于Hangfire在JSON中序列化参数,因此在序列化时冻结了第一个日期时间,因此每个后续执行都将提供相同的输出。

But one must be careful when writing a method, as he suggested. 但是,正如他建议的那样,编写方法时必须小心。

Since I was casually trying to have this all work, all my tests where written within a static class with static methods. 由于我不经意地尝试了所有这些工作,因此我的所有测试都是在带有静态方法的静态类中编写的。 And such implementation had provided the same frozen datetime issue ! 并且这样的实现提供了相同的冻结日期时间问题!

When I decided to refactor my implementation, with Job services, registered in the default ASP.Net Core IoC container, and set up to provide new service instances at every request, it not only solved the frozen output issue, but also every issue encountered with Dependency injections. 当我决定使用Job服务重构实现时,将其注册在默认的ASP.Net Core IoC容器中,并设置为在每次请求时提供新的服务实例,这不仅解决了冻结的输出问题,还解决了遇到的每个问题。依赖注入。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM