2016-09-16 4 views
2

У меня есть приложение MVC, и я пытаюсь отправить электронное письмо с помощью Hangfire и Postal. Электронная почта должна быть отправлена ​​после регистрации. Регистрация работает правильно, но работа, которую я выполняю, остается в очереди, и я не получаю никаких сообщений. Так что в моей MVC контроллер У меня есть следующий код:Hangfire background job остается в очереди

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(); 

UPDATE 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

@chris, я попытался сделать aclean и перестроить ... ничего .. Я думаю, что я не могу его отладить, потому что это фоновая работа ... или аналогичная – Ciccio

ответ

2

I Found проблему (ы):

  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

Я предполагаю, что есть что-то делать с любым

  1. вызова HostingEnvironment.MapPath(), или
  2. некоторых внутренними деталями конструкции типа EmailService.

Что меня поражает то, что есть очень много происходит в этом методе, и это можно было бы сделать значительно проще, если:

  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

Just чтобы исключить этот вопрос, и потому, что я читал, что опрос слишком часто может вызвать проблемы, вы можете удалить свой опрос и посмотреть, выполняется ли он? – user2120800

+0

Также см. Http://stackoverflow.com/questions/39485570/queuing-bankgroundjob-with-hangfire-within-an-async-action-in-asp-net-mvc-freeze Почему ваш метод async Task вместо просто пустота? Потому что он был перенесен? Снова - схватившись за соломинку - но на этот раз все стоит сделать. ;) – user2120800

 Смежные вопросы

  • Нет связанных вопросов^_^