Проект MVC поставляется с частично встроенными службами электронной почты. Я реализовал класс EmailService
, который работает нормально. Тем не менее, мне нужно отправить электронные письма навалом для нескольких пользователей, поэтому я хотел бы запустить этот процесс в фоновом режиме, и именно здесь я застрял. Я пробовал следующие коды:SendEmailAsync в фоновом режиме
//To simplify the example, I will just use the loop
for (int i = 1; i <= 10; i++)
{
//Version 1:
await UserManager.SendEmailAsync(userId + i, "Test subject line", "Sample email body");
//Version 2:
UserManager.SendEmailAsync(userId + i, "Test subject line", "Sample email body");
//Version 3:
ThreadPool.QueueUserWorkItem(o => UserManager.SendEmailAsync(userId + i, "Test subject line", "Sample email body"));
//Version 4:
Task.Run(async() => { await UserManager.SendEmailAsync(userId + i, "Test subject line", "Sample email body"); });
//Version 5:
await Task.Run(() => { UserManager.SendEmailAsync(userId + i, "Test subject line", "Sample email body"); });
}
Версия 1 является единственным рабочим кодом. Но await
заблокирует код, который вызывает длительную задержку, прежде чем перейти к следующей странице.
Версия 2, 3 и 4 не работают вообще.
Версия 5 имеет очень странное поведение. Я всегда получаю меньше электронных писем. Используя i
, чтобы отслеживать, какая электронная почта мне не хватает, она всегда является последней, которая отсутствует. (в приведенном выше примере я всегда получаю электронную почту только от userId от 1 до 9.) И если я попытаюсь отправить только одно электронное письмо, то я никогда не смогу его получить.
Что пошло не так?
Отредактировано Спасибо всем за ответ, но я, вероятно, следует отметить, что:
В то время я хочу «огонь и забыть», я почти уверен, что у меня есть все, что нужно и любой процесс, после чего не зависит от этого процесса.
Я не забочусь успех/провал этого процесса. (Возможно будет регистрировать ошибку, но не все равно много, если это не удается)
Я не совсем уверен, что вы подразумеваете под первой версией, блокирует ваш код, но как просто удалить «ожидание»? Насколько я понял, вы хотите как можно быстрее отправить содержимое страницы пользователю, не заставляя его ждать, пока все электронные письма не будут отправлены? –
Вы закрываете переменную цикла. Есть несколько сообщений, объясняющих это. Вот [один] (http://stackoverflow.com/questions/451779/how-to-tell-a-lambda-function-to-capture-a-copy-instead-of-a-reference-in-c) , Цикл Foreach изменяется в C# 5.0, но остается неизменным. Вам нужно взять копию переменной 'i', чтобы исправить ее. –
Возможный дубликат [Есть ли причина повторного использования C# переменной в foreach?] (Http://stackoverflow.com/questions/8898925/is-there-a-reason-for-cs-reuse-of-the -variable-in-a-foreach) –