如何在ASP.NET中异步发送简报(批量电子邮件)

时间:2016-05-23 13:08:59

标签: c# asp.net asynchronous

我需要向我的网站用户异步发送大约5000封电子邮件作为时事通讯..问题是我不知道以异步方式发送它们的最佳方式..请帮我更新我的代码以使其异步

我的代码:

   public string SendEmail()
    {


        foreach (var emailAddress in EmailList)

        {
            var message = new MailMessage("myemail@gmail.com", emailAddress);

            message.Subject = "hi";
            SmtpClient client = new SmtpClient("smtp.gmail.com", 587);
            client.Credentials = new NetworkCredential("myemail@gmail.com", "*****");
            client.EnableSsl = true;
            client.Send(message);
        }
        return "done";
    }

谢谢你,露西

2 个答案:

答案 0 :(得分:2)

查看asyncawait个关键字。

https://msdn.microsoft.com/en-us/library/mt674882.aspx

  

C#中的async和await关键字是异步编程的核心。通过使用这两个关键字,您可以使用.NET Framework或Windows运行时中的资源创建异步方法,就像创建同步方法一样简单。使用async和await定义的异步方法称为异步方法。

MSDN解释了事物的语法方面。更大的问题是错误处理和可靠性。将5,000封电子邮件转储到列表中并点击"发送"对他们的按钮有点乐观。这些电子邮件是否需要可靠地传递?如果其中3,000个发送会发生什么,并且网络错误突然导致临时连接丢失到外发邮件服务器?当你再次开始工作时,你会重新发送所有5,000个吗?忘掉最后的2000?接收者是否会因为重复而感到生气,或者根本没有收到消息?你打算怎么解决错误?

我发现的一种模式非常有效(无论是同步发送还是异步发送),是生成消息并将每个消息存储在数据库表中,然后使用如下内容:

public void SendAllEmails()
{
    var emails = SomeClass.GetAllUnsentEmails();

    foreach(Email message in Emails)
    {
        var success = SendEmail(message);

        if (!success)
        {
            // Do you want to do something if it fails?
        }
    }
}

public bool SendEmail(Email message)
{
    try
    {
        // 1. Send the email message
        // 2. Update the "SentOn" date in the database
        // 3. return true
    }
    catch(Exception ex)
    {
        SomeClass.CreateEmailErrorEntry(message, ex); // store error in a table or log
        return false;
    }
}

答案 1 :(得分:0)

编辑:如果在操作中使用它,则应将操作标记为异步

public async Task<ActionResult> MyAction()

首先,不要为每条消息创建SmtpClient,如下所示 而且,这应该异步发送邮件,但等待所有邮件发送

    public string SendEmail()
    {
        var tasks = new List<Task>();
        var client = new SmtpClient("smtp.gmail.com", 587);
        client.Credentials = new NetworkCredential("myemail@gmail.com", "*****");
        client.EnableSsl = true;
        foreach (var emailAddress in EmailList)
        {
            var message = new MailMessage("myemail@gmail.com", emailAddress);
            message.Subject = "hi";
            tasks.Add(client.SendMailAsync(message));
        }
        while(tasks.Count > 0)
        {
            var idx = Task.WaitAny(tasks.ToArray());
            tasks.RemoveAt(idx);
        }
        return "done";
    }