首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >SmtpClient SendAsync误差

SmtpClient SendAsync误差
EN

Stack Overflow用户
提问于 2017-07-13 14:17:28
回答 1查看 1.5K关注 0票数 0

背景

我编写了一个小型控制台应用程序,用于监视RabbitMQ队列中的电子邮件。每当一封电子邮件被推到队列中时,我的应用程序就会捡起这封电子邮件,处理并发送它。

下面是我的电子邮件服务的代码,它实际上是发送电子邮件。

代码语言:javascript
复制
public class MailService : IMailService
{
    private readonly SmtpClient _smtpClient = new SmtpClient();

    public void SendEmail(string toEmail, string subject, string body, bool isHtml)
    {
      var emailMessage = BuildEmailMessage(toEmail.Trim(), subject.Trim(), body, isHtml);
      _smtpClient.SendAsync(emailMessage, null);
    }

    #region Helpers
    private static MailMessage BuildEmailMessage(string toEmail, string subject, string body, bool isHtml)
    {
      const string fromEmailAddress = "james.brown@world.com";
      var emailMessage = new MailMessage(fromEmailAddress, toEmail, subject, body) { IsBodyHtml = isHtml };
      return emailMessage;
    }
    #endregion
}

问题

我在RabbitMQ队列中有两封电子邮件,当我启动控制台应用程序用户时,它在发送第一封电子邮件后抛出以下异常(我在收件箱中收到了第一封电子邮件)。

异步调用已经在进行中。在调用此方法之前,必须完成或取消该方法。

我做了一些调查,并看到了this thread,这解释了为什么我得到这个。显然,使用SendAsync()并不是一条路,因为:

调用SendAsync后,必须等待电子邮件传输完成后,才能尝试使用send或SendAsync发送另一条电子邮件。

那么,这方面的推荐方法是什么呢?我可以为每封电子邮件创建一个新的SmtpClient类实例,但这真的是一个好主意吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-07-14 12:12:03

同步发送电子邮件,不需要使用SendAsync的旧异步语法。另外,确保您的SmtpClient一次只从一个线程中命中,方法是将它包装在using语句中。这是一个轻微的性能损失,但你可能不会注意到,除非你发送了大量的电子邮件。如果您要发送一个吨,那么重载您的MailService.SendEmail方法来接受一个IEnumerable<EmailModel>,并使用单个SmtpClient一次性发送它们。

代码语言:javascript
复制
public void SendEmail(string toEmail, string subject, string body, bool isHtml)
{
    var emailMessage = BuildEmailMessage(toEmail.Trim(), subject.Trim(), body, isHtml);

    using(var client = new SmtpClient())
    {
        _smtpClient.Send(emailMessage);
    }      
}

//this would be the right way to do async
public async Task SendEmailAsync(string toEmail, string subject, string body, bool isHtml)
{
    var emailMessage = BuildEmailMessage(toEmail.Trim(), subject.Trim(), body, isHtml);

    using(var client = new SmtpClient())
    {
        _smtpClient.SendMailAsync(emailMessage);
    }      
}


//this would be the right way to do multiple emails
//you'd need to create an EmailModel class to contain all the details for each email (similar to MailMessage, but it would prevent your own code from taking a dependency on System.Net.Mail
public void SendEmail(IEnumerable<EmailModel> emailModels)
{

    var mailMessages = emailModels.Select(em =>  ConvertEmailModelToMailMessage(em));

    using(var client = new SmtpClient())
    {
        foreach(var mailMessage in mailMessages)
        {
            //you may want some error handling on the below line depending on whether you want all emails to attempt to send even if one encounters an error
            _smtpClient.Send(mailMessage);
        }
    }      
}

private MailMessage ConvertEmailModelToMailMessage(EmailModel emailModel)
{
    //do conversion here
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45083348

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档