2016-09-16 112 views
2

我有一个MVC应用程序,我试图用Hangfire和Postal发送一封电子邮件。电子邮件必须在注册后发送。 注册工作正常,但我运行的工作仍然排队,我没有收到任何电子邮件。 所以在我的MVC控制器我有以下代码:Hangfire后台作业仍然排队

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> 

如果我运行迟发型仪表盘我看到工作enqued

enter image description here

,但没有别的事。 我错过了什么发送电子邮件?

谢谢

UPDATE 在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); 
} 
+0

'我无法调试NotifyRegistration方法。我不知道为什么'你可能正在运行一个较旧的文件状态? – Hristo

+0

如果将呼叫移出挂火作业,是否会发送电子邮件? –

+0

@克里斯,我试图做aclean和重建......没什么。我想我不能调试它,因为是后台作业...或类似 – Ciccio

回答

2

我发现这个问题(S):

  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); 
} 
+0

使功能静态,为我做的工作。 –

0

我的猜测是有的事做与EmailService类型的任何

  1. 调用HostingEnvironment.MapPath(),或
  2. 一些内部结构的细节。

什么打动我的是,有一个可怕的很多在这个方法怎么回事,它可以作出显著简单,如果:

  1. ,而不是实例化一个新EmailService,你通过一个入含有类作为一个已经实例化的依赖关系,并且也是
  2. ,而不是试图将你的模板目录中的物理文件路径作为参数传递给方法。

如果你要执行这个重构,我会打赌一个不小数量的小猫,这个问题会消失。

+0

我抄袭http://docs.hangfire.io/en/latest/tutorials/send-email.html#installing-hangfire 他们也建议不要复杂类型传递给在backgroundjob方法来看,由于串行化:从他们的网站的方法复杂... 然而,给我几分钟,我试试您的解决方案 – Ciccio

+0

我改变了方法,你说的,但什么都没有改变,没有什么会引发异常..看到更新2 – Ciccio

+0

嗯,这样看来我欠你的几只小猫。 ... –

0

没有看到你的迟发型配置...

你有app.UseHangfireServer();地方?这就是告诉Hangfire它需要执行的操作 - 否则你只是在排队,因为它希望执行其他操作。

+0

是的,我是......不过我已经更新我的职务....所以你可以看到我做了什么... – Ciccio

+0

刚排除干扰,因为我已经阅读过频繁的查询可能会导致问题,您是否可以删除自定义轮询并查看它是否执行? – user2120800

+0

另请参阅http://stackoverflow.com/questions/39485570/queuing-bankgroundjob-with-hangfire-within-an-async-action-in-asp-net-mvc-freeze 为什么您的方法是异步任务而不是只是无效?因为它被迁移了? 再次 - 抓救命稻草 - 但一切都是值得一试,在这一点上。 ;) – user2120800

相关问题