Reputation:
I have this method I wrote that sends an email when the user presses on a button. Now the problem I am facing is that whenever a user presses on the button, the form freezes for a couple of seconds and then sends the email. So the method is working but I don't understand why the form freezes.
string emailAddress = tbEmailAddress.Text + cbEmailAddress.Text;
string emailPassword = tbEmailPassword.Text;
string emailRecipient = tbEmailRecipient.Text;
string emailSubject = tbEmailSubject.Text;
string emailBody = rtbEmailBody.Text;
string smtpHost;
string smtpPort;
MailMessage email = new MailMessage(emailAddress, emailRecipient);
email.Subject = emailSubject;
email.Body = emailBody;
SmtpClient smtp = new SmtpClient("smtp.live.com", 587);
smtp.EnableSsl = true;
smtp.Credentials = new System.Net.NetworkCredential(emailAddress, emailPassword);
smtp.Send(email);
smtp.Dispose();
Is there any way to get around this problem I am facing?
Thank you in advance.
Upvotes: 0
Views: 3788
Reputation: 22747
Use SmtpClient.SendMailAsync
:
async Task SendMail()
{
var email = CreateMailMessage();
using (var smtp = new SmtpClient("smtp.live.com", 587) {
EnableSsl = true,
Credentials = new NetworkCredential(emailAddress, emailPassword)
})
{
await smtp.SendMailAsync(email);
}
}
Upvotes: 1
Reputation: 65097
Just another solution.. that I find a lot nicer. Tasks are specifically designed to help you manage this sort of thing.. without worrying about Thread management. It also allows you to monitor when the Thread has finished executing.
If you wrap your code into its own method, you will be able to do something like this:
var sendEmailTask = Task.Run(() => yourSendEmailMethod())
.ContinueWith(t => MessageBox.Show("Email sent"));
As already stated, the issue is because your application runs on a single Thread. That Thread will be blocked during the time the email is sent. If you create a new Thread (my example uses a Task to do that), the email will be sent using that Thread.. and your applications UI will continue to function on its own Thread.
Upvotes: 1
Reputation: 1977
You can invoke the method on another Thread, try using Thread or Task. It's freezing because the UI thread is being blocked by your task thread, so you can seperate the thread to let the UI continue responding.
System.Threading.Thread execute = new System.Threading.Thread(delegate()
{ /* execute method here here */ });
Upvotes: 1
Reputation: 5664
The form freezes because you are sending the email using the default thread for your program. The same thread used by all of the windows in your app to process windows events. Whilst you are sending the email, the windows can't process any Windows messages. Place the email sending into a background thread and then your app won't be blocked.
Upvotes: 0
Reputation: 5525
The form freezes because the method needs to finish before returning control and sending mail requires some time. You could run the method asynchronously.
If you are using .NET framework 4.5 and C# 5, you can use async-await to achieve what you want. Otherwise, you can run the mail sending asynchronously using Parallel.Invoke(() => { SendMail()}),
or launch another thread to do the same.
You might also want to have a look at: Asynchronously sending a System.Net.Mail.MailMessage in C#, and the related post: Asynchronously sending Emails in C#?
Upvotes: 4