Hangfire 可以用作简单的方法计时器吗?

Can Hangfire Work as A Simple Method Timer?

我有一个 .NET Core Web API 应用程序。该应用程序包含数据库访问模型和向用户发送电子邮件的方法。我的最终目标是每晚调用一个方法(通过电子邮件通知用户他们的注册已过期并在数据库中将其标记为已过期)。

所以,简而言之,我可以构建一个端点并每晚手动调用它。或者构建一个 windows 服务来调用端点。或者构建一个 windows 服务来完成这项工作。但我想将逻辑保留在一个应用程序中。

我理想的解决方案是在我的应用程序中设置一个计时器 运行 并每 24 小时调用一次服务中的方法。当然,那是不可能的,所以我在看Hangfire。 official documentation 似乎表明有很多开销。

Hangfire keeps background jobs and other information that relates to the processing inside a persistent storage. Persistence helps background jobs to survive on application restarts, server reboots, etc.

如果我只是想调用一个方法,我需要这个吗?

Background jobs are processed by Hangfire Server. It is implemented as a set of dedicated (not thread pool’s) background threads that fetch jobs from a storage and process them. Server is also responsible to keep the storage clean and remove old data automatically.

我还需要工作吗?

有没有一种方法可以使用 Hangfire 调用方法而不需要所有这些开销?

tl;dr:是否有选项可以选择退出仪表板、数据库连接等,只让 Hangfire 作为计时器工作?

My ideal solution would be to have a timer running inside my app and calling a method in a service every 24 hours. Of course, that's not possible...

实际上,使用 IHostedService 很有可能。您应该花一些时间阅读 full documentation,但简单来说,对于您的场景,您只需要类似以下内容:

internal class NightlyEmailHostedService : IHostedService, IDisposable
{
    private Timer _timer;

    public Task StartAsync(CancellationToken cancellationToken)
    {
        _timer = new Timer(DoWork, null, TimeSpan.Zero, 
            TimeSpan.FromHours(24));
        return Task.CompletedTask;
    }

    private void DoWork(object state)
    {
        // send email
    }

    public Task StopAsync(CancellationToken cancellationToken)
    {
        _timer?.Change(Timeout.Infinite, 0);
        return Task.CompletedTask;
    }

    public void Dispose()
    {
        _timer?.Dispose();
    }
}

然后,在 Startup.cs 中添加:

services.AddHostedService<NightlyEmailHostedService>();

现在,这是一种极其幼稚的方法。它基本上只是启动一个计时器,每 24 小时 运行 一次,但取决于您的应用程序何时启动,它可能并不总是在晚上。实际上,您可能希望每分钟左右设置一次计时器 运行,并检查您实际希望电子邮件发出的特定时间。有一个 interesting implementation of handling cron-style times via an IHostedService 你可能想参考。

总而言之,很可能在您的应用程序中完成所有这些操作,而不需要像 Hangfire 这样的额外功能。但是,当然,与使用 Hangfire 之类的工具相比,您需要做更多的工作。