views:

253

answers:

4

I have a thread running in the background that will sleep and pull data from the database when something wakes it up. I am sending the emails using google apps using SmtpClient (code below).

I wanted to know if there is anything i be aware of? I plan to send only one email at a time (a registration or forgot password email). I am a little worried something can happen like an invalid email locking up the thread because i didnt set a timeout or maybe google apps happen to be done and causing the app to blow up. What should i be aware off? I should ask how i should test as well?

        var client = new SmtpClient("smtp.gmail.com", 587)
        {
            Credentials = new NetworkCredential(fromAddr, pass),
            EnableSsl = true
        };
        MailMessage mail = new MailMessage(fromAddr, toAddr, subject, body);
        mail.IsBodyHtml = true;
        client.Send(mail);
A: 

I am assuming this is being done under ASP.Net since it is one of the tags.

How important is this process? This may be a good candidate for a Windows Service rather than part of the ASP.Net runtime if your environment allows.

You've mentioned that you pull the data from the database and send the email. None of this relies on ASP.Net. Plus a service may give you better threading, testing, logging and async options.

If you want to stick with ASP.Net runtime, then you can also consider Asynchronous Pages if you haven't already. This will allow you to spawn several mail threads and have your main page thread wait for the results. You can also set a timeout value that will allow you to cancel and log stuck threads. Setting and handling an async timeout would take care of much of your worries I suspect. This solution will at least take your mail sending off your make page request thread.

Testing should be straight forward. You can register separate google accounts for testing.

kervin
A: 

Add a try/catch to the code, and you are fine. It will, at worst, eventually timeout. It won't run forever, and Google won't keep the connection open forever (in fact SMTP is pretty unforgiving when it comes to timeouts... if you are slow, it will kill the connection).

    try
    {
        var client = new SmtpClient("smtp.gmail.com", 587)
        {
            Credentials = new NetworkCredential(fromAddr, pass),
            EnableSsl = true
        };
        MailMessage mail = new MailMessage(fromAddr, toAddr, subject, body);
        mail.IsBodyHtml = true;
        client.Send(mail);
    }
    catch
    {
        // do something
    }

When it comes to testing... use a different gMail account. Also you may want to check on your limit of sent emails per day. Not sure what gMail's number is but they don't just let you send how ever many you want to send.

Clarence Klopfstein
-1: You should almost _never_ use "catch{}". It will hide all exceptions. Exceptions don't go away just because you can't see them.
John Saunders
well he did said //do something
AZ
-1?? I didn't do catch{}. I did have a comment in there for them to... do something. How am I supposed to know what they need to do?
Clarence Klopfstein
A: 

You can set the Timeout property of SmtpClient, and then handle any exceptions thrown by the Send call. Then it will not lock up the thread, though you will have to handle the cause of the exception as you deem appropriate.

Peter
+2  A: 

If you're using IIS. Install SMTP on your server an send all mail to localhost. That way if an email doesn't go through right away, the SMTP server will queue the email instead of hang your application.

You will need to configure the SMTP server to use gmail as a smarthost. If you need more information about how to configure this, let me know.

Jeremy Seekamp
This is also the way I do it - it is faster and more reliable. If any of your recipients are invalid, or their SMTP servers are down, you'll get timeouts and/or exceptions raised. This way, IIS accepts all of the mail immediately then takes care of sending the message, including retrying the sending operation if it fails.
Richard