Ana Sampaio
Ana Sampaio

Reputation: 351

Send email in a loop while overcoming the exceptions

This is my code

foreach (String Email in usersList)
{ 
   if(Regex.IsMatch(Email, @"\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*") 
   {

     SmtpClient smtpClient = new SmtpClient();
     MailMessage message = new MailMessage();
     MailAddress AddressFrom = new MailAddress(emailFrom);
     message.From = AddressFrom;
     MailAddress AddressTo = new MailAddress(Email);
     message.To.Add(Email);
     smtpClient.Send(message);
     message.Dispose();
     smtpClient.Dispose();
   }
}

I need to send an email to all users present in the list. But if an exception occurs, the loop breaks and the rest of emails won't be sent. There is other way I can do this so if an email can't be sent the loop keeps iterating and just ignore the ones that fail?

Thank you!

Upvotes: 1

Views: 3042

Answers (3)

pt12lol
pt12lol

Reputation: 2441

How about Parallel programming?

Parallel.ForEach(usersList, (string email) =>
{ 
   if(Regex.IsMatch(Email, @"\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*") 
   {
     SmtpClient smtpClient = new SmtpClient();
     MailMessage message = new MailMessage();
     MailAddress AddressFrom = new MailAddress(emailFrom);
     message.From = AddressFrom;
     MailAddress AddressTo = new MailAddress(Email);
     message.To.Add(Email);
     smtpClient.Send(message);
     message.Dispose();
     smtpClient.Dispose();
   }
});

Exception would be thrown in different threads and one thrown exception wouldn't cause breaking the other tasks. Of course you shouldn't forget to use using statement, which makes you sure that the memory will be disposed correctly. In your solution, when exception is thrown, even if it is caught message.Dispose() and smtp.Dispose() aren't executed.

Upvotes: 1

evanmcdonnal
evanmcdonnal

Reputation: 48076

Yes, but your code could use a decent amount of work.

using (SmtpClient smtpClient = new SmtpClient())
{

    foreach (String Email in usersList)
    { 
       if(Regex.IsMatch(Email, @"\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*") 
       {
         using (MailMessage message = new MailMessage())
         {
             try
             {
                 MailAddress AddressFrom = new MailAddress(emailFrom);
                 message.From = AddressFrom;
                 MailAddress AddressTo = new MailAddress(Email);
                 message.To.Add(Email);
                 smtpClient.Send(message);
              }
              catch (Exception e)
              {
                  // log exception and keep going
              }
         }
       }
    }
}

Firstly, stop calling Dispose()! When you get that exception, do you know what happens? Dispose() never gets called. Bring you smtp allocation outside of the loop so it's not re-allocated on every iteration. Then just add a try-catch and suppress the exceptions, log them, write them to the console, whatever.

Upvotes: 7

Adriano Carneiro
Adriano Carneiro

Reputation: 58595

How about using "try catch", a.k.a. Exception Handling Statements?

http://msdn.microsoft.com/en-us/library/0yd65esw(v=vs.110).aspx

You code would look like this:

//you don't need a SmtpClient for each recipient
SmtpClient smtpClient = new SmtpClient();

foreach (String Email in usersList)
{ 
   if(Regex.IsMatch(Email, @"\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*") 
   {
     using (MailMessage message = new MailMessage()){
         try
         {
            MailAddress AddressFrom = new MailAddress(emailFrom);
            message.From = AddressFrom;
            MailAddress AddressTo = new MailAddress(Email);
            message.To.Add(Email);
            smtpClient.Send(message);
         } 
         catch (Exception ex)
         {
            Console.WriteLine(ex.Message);
         }
     }
   }
}

Upvotes: 4

Related Questions