Hangfire 后台作业保持排队状态

问题描述 投票:0回答:4

我有一个 MVC 应用程序,我正在尝试使用 Hangfire 和 Postal 发送电子邮件。该电子邮件必须在注册后发送。 注册工作正常,但我运行的作业仍处于排队状态,并且我没有收到任何电子邮件。 所以在我的 MVC 控制器中我有以下代码:

public async Task<ActionResult> Register(RegisterViewModel model)
{
    //register correctly the user

    //I send the email
    BackgroundJob.Enqueue(() => 
        NotifyRegistration(user.Id, user.UserName, user.Email)   
    );

    ...
 }

[AutomaticRetry(Attempts = 5)]
public async Task NotifyRegistration(string userId, string username, string email)
{
    //I calculate callbackUrl

    var viewsPath = Path.GetFullPath(HostingEnvironment.MapPath(@"~/Views/Emails"));
    var engines = new ViewEngineCollection();
    engines.Add(new FileSystemRazorViewEngine(viewsPath));

    var emailService = new EmailService(engines);

    var emailToSend = new NewRegisteredUserEmail
    {
        To = email, UserName = username, CallbackUrl = callbackUrl 
    };

    emailService.Send(emailToSend);
}

我无法调试NotifyRegistration方法。我不知道为什么。我使用的是邮政,所以 EmailService 不是我的实现。这是我如何配置 smtp 服务的:

<system.net>
  <mailSettings>
    <smtp deliveryMethod="Network">
      <network host="smtp.live.com" port="25" enableSsl="true" userName="***" password="***"></network>
    </smtp>
  </mailSettings>
</system.net>

如果我运行hangfire仪表板,我会看到作业已排队

但是没有发生其他事情。 发送电子邮件时我错过了什么?

谢谢你

更新 在startup.cs中我写了这个:

var options = new SqlServerStorageOptions
{
    QueuePollInterval = TimeSpan.FromSeconds(1)
};

GlobalConfiguration.Configuration
     .UseSqlServerStorage("DbConnectionString", options)
     .UseFilter(new LogEmailFailureAttribute());

 app.UseHangfireDashboard();
 app.UseHangfireServer();

更新2 我这样改造了我的NotifyRegistration:

[AutomaticRetry(Attempts = 5)]
public async Task NotifyRegistration(string userId, string username, string email, EmailService emailService)
{
    //I calculate callbackUrl

    var emailToSend = new NewRegisteredUserEmail
    {
        To = email, UserName = username, CallbackUrl = callbackUrl 
    };

    emailService.Send(emailToSend);
}
c# asp.net-mvc-5 hangfire postal
4个回答
7
投票

我发现了问题:

  1. 不支持sql server版本。我使用的是 2005。支持的数据库是 2008R2 及更高版本:http://docs.hangfire.io/en/latest/configuration/using-sql-server.html

  2. NotifyRegistration 方法必须是静态的: https://discuss.hangfire.io/t/jobs-in-enqueue-state-most-never-run/2367/4

.

[AutomaticRetry(Attempts = 5)]
public static void NotifyRegistration(string userId, string username, string email, EmailService emailService)
{
    //I calculate callbackUrl

    var emailToSend = new NewRegisteredUserEmail
    {
        To = email, UserName = username, CallbackUrl = callbackUrl 
    };

    emailService.Send(emailToSend);
}

1
投票

没有看到你的 Hangfire 配置...

你有

app.UseHangfireServer();
吗?这就是告诉 Hangfire 它需要执行的内容 - 否则你只是在排队,因为它期望其他东西来执行执行。


0
投票

我的猜测是这与其中之一有关

  1. 对 HostingEnvironment.MapPath() 的调用,或
  2. EmailService 类型的一些内部构造细节。

令我印象深刻的是,这种方法中发生了很多事情,如果满足以下条件,它可以变得更加简单:

  1. 您不是实例化一个新的 EmailService,而是将一个作为已实例化的依赖项传递到包含的类中,并且
  2. 而不是尝试从方法中推测模板目录的物理文件路径,而是将其作为参数传递到方法中。

如果你要执行此重构,我敢打赌,很多小猫都会相信这个问题会消失。


0
投票

顺便提一下

当您以编程方式从“alpha”队列添加计划作业但计划作业排入不同队列时,也会发生这种情况。

因此在添加计划作业时提及队列名称 alpha 解决了我的问题

© www.soinside.com 2019 - 2024. All rights reserved.