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

时间:2018-10-08 17:06:28

标签: asp.net-core-webapi hangfire

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

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

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

  

Hangfire将后台作业和其他与处理相关的信息保留在持久性存储中。持久性可帮助后台作业在应用程序重新启动,服务器重新启动等情况下得以生存。

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

  

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

我什至需要工作吗?

是否有一种方法可以在没有使用Hangfire的所有开销的情况下仅调用方法?

tl; dr:是否有一些选项可以退出仪表板,数据库连接等,而只是将Hangfire用作计时器?

1 个答案:

答案 0 :(得分:3)

  

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

实际上,很可能使用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这样的工具相比,您要做的工作要多得多。