2013-10-02 2 views
0

У меня есть этот метод, который я написал, который отправляет электронное письмо, когда пользователь нажимает кнопку. Теперь проблема, с которой я сталкиваюсь, заключается в том, что всякий раз, когда пользователь нажимает на кнопку, форма замерзает на пару секунд, а затем отправляет электронное письмо. Поэтому метод работает, но я не понимаю, почему форма замораживается.Форма Замораживает при выполнении метода

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(); 

Есть ли способ обойти эту проблему, с которой я столкнулся?

Заранее спасибо.

+0

Посмотри многопоточность – JleruOHeP

+0

Сделайте вызов асинхронный, существует много методов в классе 'SmtpClient', чтобы сделать это, посмотри в [this] (http://msdn.microsoft.com/en-us/library/x5x13z6h.aspx) и [this] (http://msdn.microsoft.com/en-us/library/hh193922.aspx) , –

ответ

4

Форма замораживается, потому что метод должен закончить, прежде чем возвращать управление и отправлять почту требует некоторого времени. Вы можете запустить метод асинхронно.

Если вы используете .NET framework 4.5 и C# 5, вы можете использовать async-await для достижения того, чего хотите. В противном случае вы можете выполнить асинхронную отправку почты с помощью Parallel.Invoke(() => { SendMail()}), или запустить другой поток, чтобы сделать то же самое.

Вы также можете захотеть взглянуть на: Asynchronously sending a System.Net.Mail.MailMessage in C#, и связанное с этим сообщение: Asynchronously sending Emails in C#?

0

Форма замерзает, потому что вы посылаете электронную почту, используя нить по умолчанию для вашей программы. Тот же поток, используемый всеми окнами в вашем приложении для обработки событий Windows. Пока вы отправляете электронное письмо, окна не могут обрабатывать любые сообщения Windows. Поместите отправку электронной почты в фоновый поток, а затем ваше приложение не будет заблокировано.

0

Вы можете вызвать метод в другом потоке, попробуйте использовать Thread или Task. Это замерзает, потому что поток пользовательского интерфейса блокируется потоком задачи, поэтому вы можете отделить поток, чтобы пользовательский интерфейс продолжал отвечать.

System.Threading.Thread execute = new System.Threading.Thread(delegate() 
{ /* execute method here here */ }); 
1

Просто другое решение .., что я нахожу намного приятнее. Задачи специально разработаны, чтобы помочь вам справиться с такими вещами .. не беспокоясь об управлении потоками. Он также позволяет вам отслеживать, когда Thread завершил выполнение.

Если вы обернуть свой код в свой собственный метод, вы будете в состоянии сделать что-то вроде этого:

var sendEmailTask = Task.Run(() => yourSendEmailMethod()) 
          .ContinueWith(t => MessageBox.Show("Email sent")); 

Как уже говорилось, проблема в том, что ваше приложение работает на одном потоке. Эта тема будет заблокирована во время отправки электронной почты. Если вы создаете новый поток (мой пример использует задачу для этого), электронное письмо будет отправлено с использованием этого потока .. и ваш пользовательский интерфейс приложений будет продолжать функционировать в своем собственном потоке.

+0

Будучи операцией с привязкой к IO, вам действительно не нужно тратить поток ниток для этого. –

1

Вы должны использовать SmtpClient.SendMailAsync (.NET 4.5) или SendAsync:

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); 
    } 
} 
Смежные вопросы