I'm developing an application where a user clicks/presses enter on a certain button in a window, the application does some checks and determines whether to send out a couple of emails or not, then show another window with a message.
My issue is, sending out the 2 emails slows the process noticeably, and for some (~8) seconds the first window looks frozen while it's doing the sending.
Is there any way I can have these emails sent on the background and display the next window right away?
Please don't limit your answer with "use X class" or "just use X method" as I am not all too familiarized with the language yet and some more information would be highly appreciated.
Thanks.
As of .NET 4.5 SmtpClient implements async awaitable method SendMailAsync
. As a result, to send email asynchronously is as following:
public async Task SendEmail(string toEmailAddress, string emailSubject, string emailMessage) { var message = new MailMessage(); message.To.Add(toEmailAddress); message.Subject = emailSubject; message.Body = emailMessage; using (var smtpClient = new SmtpClient()) { await smtpClient.SendMailAsync(message); } }
As it's a small unit of work you should use ThreadPool.QueueUserWorkItem for the threading aspect of it. If you use the SmtpClient class to send your mail you could handle the SendCompleted event to give feedback to the user.
ThreadPool.QueueUserWorkItem(t => { SmtpClient client = new SmtpClient("MyMailServer"); MailAddress from = new MailAddress("[email protected]", "My Name", System.Text.Encoding.UTF8); MailAddress to = new MailAddress("[email protected]"); MailMessage message = new MailMessage(from, to); message.Body = "The message I want to send."; message.BodyEncoding = System.Text.Encoding.UTF8; message.Subject = "The subject of the email"; message.SubjectEncoding = System.Text.Encoding.UTF8; // Set the method that is called back when the send operation ends. client.SendCompleted += new SendCompletedEventHandler(SendCompletedCallback); // The userState can be any object that allows your callback // method to identify this send operation. // For this example, I am passing the message itself client.SendAsync(message, message); }); private static void SendCompletedCallback(object sender, AsyncCompletedEventArgs e) { // Get the message we sent MailMessage msg = (MailMessage)e.UserState; if (e.Cancelled) { // prompt user with "send cancelled" message } if (e.Error != null) { // prompt user with error message } else { // prompt user with message sent! // as we have the message object we can also display who the message // was sent to etc } // finally dispose of the message if (msg != null) msg.Dispose(); }
By creating a fresh SMTP client each time this will allow you to send out emails simultaneously.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With