Hangfire 后台作业保持排队
Hangfire background job remain enqueued
我有一个 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 方法。我不知道为什么。我使用的是 Postal,所以 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);
}
我的猜测是这与两者都有关
- 对 HostingEnvironment.MapPath() 的调用,或
- EmailService 类型的一些内部构造细节。
令我印象深刻的是,此方法中发生了很多事情,如果满足以下条件,它可以变得更加简单:
- 您没有实例化一个新的 EmailService,而是将一个作为已经实例化的依赖项传递给包含的 class,并且
- 与其尝试从方法中推测模板目录的物理文件路径,不如将其作为参数传递给方法。
如果您要执行此重构,我敢打赌这个问题会消失。
没有看到你的 Hangfire 配置...
你有app.UseHangfireServer();
吗?这就是告诉 Hangfire 它需要执行的内容 - 否则你只是在排队,因为它期望其他东西来执行。
我发现了问题:
不支持 sql 服务器的版本。我使用的是 2005。支持的数据库是 2008R2 及更高版本:http://docs.hangfire.io/en/latest/configuration/using-sql-server.html
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);
}
我有一个 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 方法。我不知道为什么。我使用的是 Postal,所以 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);
}
我的猜测是这与两者都有关
- 对 HostingEnvironment.MapPath() 的调用,或
- EmailService 类型的一些内部构造细节。
令我印象深刻的是,此方法中发生了很多事情,如果满足以下条件,它可以变得更加简单:
- 您没有实例化一个新的 EmailService,而是将一个作为已经实例化的依赖项传递给包含的 class,并且
- 与其尝试从方法中推测模板目录的物理文件路径,不如将其作为参数传递给方法。
如果您要执行此重构,我敢打赌这个问题会消失。
没有看到你的 Hangfire 配置...
你有app.UseHangfireServer();
吗?这就是告诉 Hangfire 它需要执行的内容 - 否则你只是在排队,因为它期望其他东西来执行。
我发现了问题:
不支持 sql 服务器的版本。我使用的是 2005。支持的数据库是 2008R2 及更高版本:http://docs.hangfire.io/en/latest/configuration/using-sql-server.html
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);
}