我想异步发送多封电子邮件。电子邮件发送后,电子邮件不会相互依赖,也不会运行任何代码,因此我想解雇多个并忘记。我正在关注this article发送异步电子邮件,但我不确定我是否正在发送多封电子邮件。
我的一些担忧;
public class MyController : Controller
{
public async Task SendEmailAsync(IdentityMessage message)
{
var mailMessage = new MailMessage
("abc@domain.com", message.Destination, message.Subject, message.Body);
using(var client = new SmtpClient())
{
await client.SendMailAsync(mailMessage);
}
}
public ActionResult Create()
{
Action<CancellationToken> workItem = SendEmails;
HostingEnvironment.QueueBackgroundWorkItem(workItem);
return View();
}
private async void SendEmails(CancellationToken cancellationToken)
{
await SendEmailAsync(new IdentityMessage(...));
await SendEmailAsync(new IdentityMessage(...));
}
}
答案 0 :(得分:1)
在SendEmails中,每个下一封电子邮件都在等待之前的完成,您应该像这样重写:
private async Task SendEmails(CancellationToken cancellationToken)
{
await Task.WhenAll(SendEmailAsync(new IdentityMessage(...)),
SendEmailAsync(new IdentityMessage(...)));
}
通过这样做,所有电子邮件将并行发送。 你也不应该在Create中使用QueueBackgroundWorkItem。你可以做下一个:
public async Task<ActionResult> Create()
{
HostingEnvironment.QueueBackgroundWorkItem(async (token)=> await SendEmails() );
return View();
}
但请记住,如果SendEmails发生任何异常,您将不会收到有关此事件的通知。如果这对您来说可能是一个问题,请告诉我,所以我会为此提供解决方案。
但我更喜欢从网络应用程序发送电子邮件的另一种方法。它更复杂但更可靠。 Web应用程序永远不应该向smtp服务器发送消息,而是将请求存储到队列或数据库。比我们有后台应用程序监听队列,每次检测到新请求时,它尝试将其发送到smtp。如果尝试失败,系统会将请求返回队列,稍后会再尝试几次。如果您的应用程序托管在azure中,此后台应用程序可能是webjob的Windows服务。 这种方法的优点:
缺点: