.Net 6 使用HangFire(三)

发布时间 2023-06-08 15:36:16作者: 开心的菜鸟程序猿

本章节要介绍创建后台作业时如何传递参数。

 你可以像普通方法传递参数一样,往后台作业中传递额外的数据(方法参数),在后台作业执行的时候,这些参数会被Console.WriteLine方法使用。

1 BackgroundJob.Enqueue(() => Console.WriteLine("Hello, {0}!", "world"));
View Code

如之前说过的,HangFire会使用强大的使用Newtonsoft.JSON包把后台作业的信息序列化为JSON字符串,所以你可以传递绝大多数数据类型的参数,包括数组、自定义对象、集合等。但是不支持传递ref和out关键字修饰的参数。 

因为这些参数是会被序列化的,这可能需要你仔细的考虑它们的值,更有效率的做法是把参数具体的值存储在应用的数据库中,而把相应的标识符传递到后台作业中。后台作业可能会在几天或几周后才被执行,如果你使用的数据在这期间被更改了或者被删除了,这可能会导致一些问题,需要你对这些场景做好相应的处理并相应的设计你的后台作业。

本章节介绍如何在后台作业中传递依赖。

在绝大多数时候,你都想要运行后台作业的时候使用应用中的其它类来完成不同的工作,以此来保持代码的简单和整洁。这时候你可以把这些类当成依赖来调用。HangFire允许你在后台调用实例方法。假设你有以下一个类,这个类使用DBcontext来访问数据库,并用 EmailService 来发送邮件。

 1 public class EmailSender
 2 {
 3     public void Send(int userId, string message)
 4     {
 5         var dbContext = new DbContext();
 6         var emailService = new EmailService();
 7 
 8         // Some processing logic
 9     }
10 }
View Code

为了在后台调用Send方法,可以使用 如下Enquequ方法(BackgroundJob类的其它方法也提供了类似的方法)的重载:

1 BackgroundJob.Enqueue<EmailSender>(x => x.Send(13, "Hello!"));
View Code

当工作线程确定它需要调用某个实例方法时,它首先使用当前的JobActivator类实例来创建给定类(比如上面的EmailSender类)的实例。HangFire默认使用 Activator.CreateInstance方法,通过给定类的默认构造函数来创建实例。所以上面的代码需要做如下处理(添加默认构造函数):

 1 public class EmailSender
 2 {
 3     private IDbContext _dbContext;
 4     private IEmailService _emailService;
 5 
 6     public EmailSender()
 7     {
 8         _dbContext = new DbContext();
 9         _emailService = new EmailService();
10     }
11 
12     // ...
13 }
View Code

如果你想要给定类可用于单元测试,可以考虑添加一个构造函数重载方法,因为默认的Activator没法为没有默认构造函数的类创建实例,所以需要做如下处理(添加一个有参数的构造函数):

 1 public class EmailSender
 2 {
 3     // ...
 4 
 5     public EmailSender()
 6         : this(new DbContext(), new EmailService())
 7     {
 8     }
 9 
10     internal EmailSender(IDbContext dbContext, IEmailService emailService)
11     {
12         _dbContext = dbContext;
13         _emailService = emailService;
14     }
15 }
View Code

如果你使用AutoFac、Ninject等IOC容器,你可以移除默认构造函数,在下一章节会介绍如何做到这一点。

Passing Dependencies — Hangfire Documentation