When a user registers on my website, I don\'t see why I need to make him \"wait\" for the smtp to go through so that he gets an activation email.
I decided I want to
Use this way-
private void email(object parameters)
{
Array arrayParameters = new object[2];
arrayParameters = (Array)parameters;
string Email = (string)arrayParameters.GetValue(0);
string subjectEmail = (string)arrayParameters.GetValue(1);
if (Email != "Email@email.com")
{
OnlineSearch OnlineResult = new OnlineSearch();
try
{
StringBuilder str = new StringBuilder();
MailMessage mailMessage = new MailMessage();
//here we set the address
mailMessage.From = fromAddress;
mailMessage.To.Add(Email);//here you can add multiple emailid
mailMessage.Subject = "";
//here we set add bcc address
//mailMessage.Bcc.Add(new MailAddress("bcc@site.com"));
str.Append("<html>");
str.Append("<body>");
str.Append("<table width=720 border=0 align=left cellpadding=0 cellspacing=5>");
str.Append("</table>");
str.Append("</body>");
str.Append("</html>");
//To determine email body is html or not
mailMessage.IsBodyHtml = true;
mailMessage.Body = str.ToString();
//file attachment for this e-mail message.
Attachment attach = new Attachment();
mailMessage.Attachments.Add(attach);
mailClient.Send(mailMessage);
}
}
protected void btnEmail_Click(object sender, ImageClickEventArgs e)
{
try
{
string To = txtEmailTo.Text.Trim();
string[] parameters = new string[2];
parameters[0] = To;
parameters[1] = PropCase(ViewState["StockStatusSub"].ToString());
Thread SendingThreads = new Thread(email);
SendingThreads.Start(parameters);
lblEmail.Visible = true;
lblEmail.Text = "Email Send Successfully ";
}
If you are using .Net's SmtpClient and MailMessage classes, you should take note of a couple things. First, expect errors on the send, so trap and handle them. Second, in .Net 4 there were some changes to these classes, and both now implement IDisposable (MailMessage since 3.5, SmtpClient new in 4.0). Because of this, your creation of the SmtpClient and the MailMessage should be wrapped in using blocks or explicitly disposed. This is a breaking change some people are unaware of.
See this SO question for more info on disposing when using async sends:
What are best practices for using SmtpClient, SendAsync and Dispose under .NET 4.0
So, why not have a separate poller/service which deals exclusively with sending emails? Thus, allowing your registration post-back to execute in only the time it takes to write to the database/message queue and delaying the sending of the email til the next polling interval.
I'm pondering the same issue just now and I'm thinking that I really don't want to even initiate the email sending within the server post back request. The process behind serving the web pages should be interested in getting a response back to the user ASAP, the more work you try to do the slower it will be.
Have a look at the Command Query Segregation Principal (http://martinfowler.com/bliki/CQRS.html). Martin Fowler explains that different models can be used in the command part of an operation than are used in the query part. In this scenario the command would be "register user", the query would be the activation email, using the loose analogy. The pertinent quote would probably be:
By separate models we most commonly mean different object models, probably running in different logical processes
Also worth a read is the Wikipedia article on CQRS (http://en.wikipedia.org/wiki/Command%E2%80%93query_separation). An important point which this highlights is:
it is clearly intended as a programming guideline rather than a rule for good coding
Meaning, use it where your code, program execution and programmer understanding would benefit. This being a good example scenario.
This approach has the added benefit of negating all the mufti-threading concerns and the headaches all that can bring.