3

This is my code to send lots of emails. I want to optimize this code to be sure that it will work and can successfully send all emails. What should I do? I know that putting interrupts between sending might be useful but how can I do this?

The main problem is avoiding classify emails as spam and decreasing number of failed sent emails.

var list = from c in context.Emails orderby c.EmailAddress select c.EmailAddress;
MailMessage mail = new MailMessage();
try
{
    mail.From = new MailAddress(txtfrom.Text);
    foreach (var c in list)  
    {  
        mail.To.Add(new MailAddress(c.ToString()));
    }
    mail.Subject = txtSub.Text;
    mail.IsBodyHtml = true;
    mail.Body = txtBody.Text;
    if (FileUpload1.HasFile)
    {
        mail.Attachments.Add(new Attachment(
           FileUpload1.PostedFile.InputStream, FileUpload1.FileName));
    }
    SmtpClient smtp = new SmtpClient();
    smtp.Send(mail); 
}
catch (Exception)
{
    //exception handling
}
Carsten
  • 11,287
  • 7
  • 39
  • 62
Hadi Nemati
  • 547
  • 3
  • 11
  • 23
  • Use a local relay server and send everything through that. That will allow your code to send it fast, and you can configure it to retry on failure. – vcsjones Apr 03 '12 at 15:48
  • 2
    Lot's of details about sending e-mails in [this answer](http://stackoverflow.com/a/3905805/861565). – Josh Darnell Apr 03 '12 at 16:03
  • Email is a minefield and as of 2005, send-email systems can no longer be relied upon to deliver a series of characters from one computer to another computer. The problem is that acknowledgements, the cornerstone of what made email strong, have been completely removed. So Email is now a "Send and Pray", asynchronous protocol. The only way to know if the recipient received the email is to have a program run on the target machine or to ask the recipient. This was caused by spammers, Read this: http://www.codinghorror.com/blog/2008/11/is-email-efail.html – Eric Leschinski Apr 24 '13 at 14:09

2 Answers2

3

I would advise you against adding all reciepients into the same mail message.

Rather use this code:

mail.From = new MailAddress(txtfrom.Text);
mail.Subject = txtSub.Text;
mail.IsBodyHtml = true;
mail.Body = txtBody.Text;
if (FileUpload1.HasFile)
{
    mail.Attachments.Add(new Attachment(FileUpload1.PostedFile.InputStream, FileUpload1.FileName));
}
SmtpClient smtp = new SmtpClient();
foreach (var c in list)  
{  
    mail.To.Clear();
    mail.To.Add(new MailAddress(c.ToString()));
    smtp.Send(mail);
}
citronas
  • 19,035
  • 27
  • 96
  • 164
  • Very true. Most spam filters will kill emails with more than 20 recipients. – tgolisch Apr 24 '13 at 14:12
  • 2
    +1, especially as they're all going in the `To` field rather than the `Bcc` field. If the recipients don't know each other, you've just revealed their PII to every other recipient. – Richard Deeming Apr 24 '13 at 14:13
1

With a little due diligence, this can be accomplished with a very simple console application which can be called from the Web form to dispatch the emails. By diligence, I mean to insert a pause between batches so that the mail server won't get bogged down. For example, if you were grabbing the addresses from a DB and sending them out, you could have something like:

if ((count >= 100) && (count % 100 == 0))
    Thread.Sleep(30000);
-----------------------------------------

// Web form code-behind

// Pass subject and message strings as params to console app

ProcessStartInfo info = new ProcessStartInfo();

string arguments = String.Format(@"""{0}"" ""{1}""",
     subjectText.Text.Replace(@"""", @""""""),
     messageText.Text.Replace(@"""", @""""""));
info.FileName = MAILER_FILEPATH;

Process process = Process.Start(info.FileName, arguments);
Process.Start(info);

More info here: Calling Console Application from Web Form

IrishChieftain
  • 15,108
  • 7
  • 50
  • 91