首页 > 解决方案 > Hangfire 可以作为一个简单的方法计时器工作吗?

问题描述

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

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

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

Hangfire 将后台作业和与处理相关的其他信息保存在持久存储中。持久性有助于后台作业在应用程序重新启动、服务器重新启动等情况下继续存在。

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

后台作业由 Hangfire Server 处理。它被实现为一组专用的(不是线程池的)后台线程,它们从存储中获取作业并处理它们。服务器还负责保持存储清洁并自动删除旧数据。

我什至需要工作吗?

有没有办法用 Hangfire 调用一个没有所有这些开销的方法?

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

标签: asp.net-core-webapihangfire

解决方案


我理想的解决方案是在我的应用程序中运行一个计时器,并每 24 小时在服务中调用一个方法。当然,这是不可能的……

实际上,很有可能使用IHostedService. 您应该花一些时间阅读完整的文档,但简单地说,对于您的场景,您只需要以下内容:

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 小时运行一次的计时器,但取决于您的应用程序何时启动,它可能并不总是在晚上。实际上,您可能希望每分钟左右运行一次计时器,并检查您真正希望电子邮件发出的特定时间。通过IHostedService您可能想要参考的处理 cron 风格的时间,有一个有趣的实现。

总而言之,很可能在您的应用程序中完成所有这些操作,而无需像 Hangfire 这样的附加功能。但是,当然,您必须比使用 Hangfire 之类的工具多做一些工作。


推荐阅读