【问题标题】:WebApi Controller - Send Mail AsyncWebApi 控制器 - 异步发送邮件
【发布时间】:2015-07-28 09:56:59
【问题描述】:

我有一个 WebApi 控制器,其中一个部分是向一组用户发送电子邮件。

[HttpPost]
[Authorize]
[Route("{id}/Do")]
public async Task<HttpResponseMessage> Post(int id, Model model)
...
    await _emailService.SendAsync(message);
...

现在是发送电子邮件的方法(SendGrid)

public override async Task SendAsync(MailMessage message)
{
    var client =
      new SmtpClient(SendGridServerName, SendGridServerPort)
      {
          Port = SendGridServerPort,
          DeliveryMethod = SmtpDeliveryMethod.Network,
          UseDefaultCredentials = false
      };

    var credentials = new NetworkCredential(SendGridUserName, SendGridPassword);

    client.EnableSsl = true;
    client.Credentials = credentials;
    message.From = new MailAddress(FromAddress);

    await client.SendMailAsync(message);
}

一切正常,但速度很慢。我期待它很快,但await _emailService.SendAsync(message); 似乎不是异步的。它在那里停了一会儿。

有什么想法吗?

谢谢

【问题讨论】:

  • 看看WebApi Async。 “单个请求可能会稍微慢一些”,但是当系统处于负载状态时,它会表现得更好。斯蒂芬克利假设电子邮件客户端是 SmtpServer,您最好使用new thread,这样您的操作就不会等待此完成。
  • 我建议改用SendGrid SDK,他们有Async 使用REST API 的方法。
  • 我刚刚更新了原始答案,指出了一些额外的细节,说明你可以做些什么来给你的用户提供一个快速的答案。

标签: c# email asynchronous asp.net-web-api sendgrid


【解决方案1】:

async 所做的是允许您的服务器在异步执行慢速方法时运行其他线程。即,当您 await 用于异步方法时,服务器会执行不同的线程,直到 async 方法完成执行,然后继续运行调用异步方法的线程。控制器中的异步操作在幕后以完全相同的方式处理。因此,在async 电子邮件发送完成之前,您的async 操作对浏览器的响应不会发生。

注意:例如,如果电子邮件服务器或 DNS 解析存在连接问题,您通常会在 30 秒后超时,因此您的线程将在 30 秒内休眠,并且只有然后将答案发送到浏览器

如果你想快速将响应返回给你的浏览器,你需要实现一个不同的想法,即启动一个新的线程来发送电子邮件,但不要等待它完成,这样你的线程就会保持运行并立即将答案返回给浏览器。这就是众所周知的一劳永逸。要了解我在说什么,请参阅:Fire and forget approach。然后仔细阅读其他内容:Fire and Forget (Asynch) ASP.NET Method Call。考虑到 MVC 本身是线程化的,在使用“即发即弃”方法时需要考虑到这一点。

很明显,一发不可收拾,控制器将无法在电子邮件发送过程中检测到错误,因为新线程在主线程已经完成时自行运行。所以你必须实现一些东西来至少记录可能的错误,并且理想情况下让用户现在发生了什么(例如他稍后可以看到的报告)。请看这个:ASP.NET Exception Handling in background threads

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-14
    • 1970-01-01
    • 2016-03-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多